shhh <- suppressPackageStartupMessages # It's a library, so shhh!

shhh(library( mgcv ))
shhh(library(dplyr))
shhh(library(ggplot2))
shhh(library(lme4))
shhh(library(tidymv))
shhh(library(gamlss))
shhh(library(gsubfn))
shhh(library(lmerTest))
shhh(library(tidyverse))
shhh(library(boot))
shhh(library(rsample))
shhh(library(plotrix))
shhh(library(ggrepel))
shhh(library(mgcv))

shhh(library(brms))
shhh(library(bayesplot))
shhh(library(patchwork))
shhh(library(MASS))
shhh(library(tidyr))
shhh(library(extraDistr))
shhh(library(purrr))
# For exercises with Stan code
shhh(library(rstan))
options(mc.cores = parallel::detectCores())
rstan_options(auto_write = FALSE)

shhh(library(car))
shhh(library(coda))
shhh(library(gridExtra))

theme_set(theme_bw())
options(digits=4)
options(scipen=999)
set.seed(444)
pipe_message = function(.data, status) {message(status); .data}

Read in MoTR Data


rate = 160

file_prefix = "../data/provo_f160/"
fnames = list.files(path=file_prefix)

df = data.frame()
for (f in fnames) {
  temp = read.csv(paste0(file_prefix, "/", f)) %>%
    mutate(subj = str_remove(f, "_reading_measures.csv"))
  df = rbind(df, temp)
}

# Filter out readers whose accuracy to the comprehension questions were less than 80%.
filter_df = df %>%
  group_by(para_nr, subj) %>% summarise(correct = if_else(unique(correctness) == 1, 1, 0)) %>% ungroup() %>%
  drop_na() %>%
  group_by(subj) %>% summarise(p_correct = mean(correct)) %>% ungroup() %>%
  mutate(p_correct = round(p_correct, digits = 2))
`summarise()` has grouped output by 'para_nr'. You can override using the `.groups` argument.
filter_df = filter_df %>% filter(p_correct < 0.8)
filter_list = filter_df$subj
pilot_exceptions <- c("reader_255", "reader_256", "reader_259", "reader_261", "reader_262", "reader_263")

raw_df = df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  mutate(word = str_trim(word)) %>%
  mutate(subj = str_remove(subj, "reader_")) %>%
  mutate(subj = as.character(subj)) %>%
  mutate(FPReg = if_else(total_duration == 0, -1, FPReg)) %>% #If the word is skipped we can't say that it wasn't regressed on the first pass. Set to a "NA"
  mutate(skip = if_else(FPFix == 1, 0, 1)) %>% # use the same defination as in provo paper
  dplyr::select(subj, expr_id, cond_id, para_nr, word, word_nr, first_duration, total_duration, gaze_duration, go_past_time, FPReg, skip) %>%
  gather(metric, value, 7:10) %>%
  group_by(para_nr, subj, metric, cond_id, expr_id) %>%
  mutate(fixed = if_else(value > 0, 1, 0),
         n_fixed = sum(fixed),
         n_words = n()) %>%
    ungroup() %>%
  mutate(fix_threshold = n_fixed > (n_words / 5)) %>%
  mutate(skimming = if_else(fix_threshold == F,T, F)) %>%
  filter(skimming == F) %>%
  spread(metric, value) %>%
  dplyr::select(-fixed, -n_fixed, -n_words, -fix_threshold, -skimming)
length(unique(raw_df$subj))
[1] 98
# View(raw_df)

df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  filter(FPReg >= 0) %>%
  dplyr::select(FPReg) %>%
  drop_na() %>%
  summarise( m = mean(FPReg))

df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  dplyr::select(FPFix) %>%
  drop_na() %>%
  summarise( m = mean(FPFix))
NA
NA
View(raw_df)
# Average across subjects
motr_agg_df = raw_df %>%
  gather(metric, value, 7:12) %>%
    filter(value >= 0) %>% #Removes the "NA" values for FPReg
  
    # ==== Remove skipped words
    mutate(zero = if_else(!metric %in% c("FPReg", "skip") & value == 0,T, F)) %>%
    filter(zero == F) %>%
  
    drop_na() %>%
    group_by(para_nr, word_nr, word, metric) %>%
    
    # === Remove outliers > 3SD
      # mutate(outlier = if_else(metric != "FPReg" & value > (mean(value) + 3 * sd(value)), T, F)) %>% filter(outlier == F) %>%
  
      summarise(value = mean(value), nsubj = length(unique(subj))) %>%
  ungroup() %>%
  arrange(para_nr, word_nr) %>%
  rename(text_id = para_nr, word_text_idx = word_nr, motr_value = value)
`summarise()` has grouped output by 'para_nr', 'word_nr', 'word'. You can override using the `.groups` argument.
# View(motr_agg_df)

Comparison to Provo

# Read in Provo surprisal, frequency and length data
provo_modeling_df = read.csv("../data/provo_stats.csv") %>%
  dplyr::select(text_id, sent_id, trigger_idx, word, freq, surp, len) %>%
  rename(word_idx = trigger_idx)

provo_modeling_df
NA
# Read in Provo eyetracking data

provo_raw_df = read.csv("../data/provo_eyetracking.csv")

# unique(provo_raw_df$Participant_ID)
# length(unique(provo_raw_df$Participant_ID))

provo_eyetracking_df = provo_raw_df %>%
  dplyr::select(Participant_ID, Text_ID, Sentence_Number, Word_In_Sentence_Number, Word, Word_Number, IA_FIRST_FIX_PROGRESSIVE, IA_FIRST_RUN_DWELL_TIME, IA_DWELL_TIME, IA_REGRESSION_PATH_DURATION, IA_REGRESSION_OUT, IA_SKIP) %>%
  rename( #first_duration = IA_FIRST_FIXATION_DURATION,   
          gaze_duration = IA_FIRST_RUN_DWELL_TIME,
          total_duration = IA_DWELL_TIME,
          go_past_time = IA_REGRESSION_PATH_DURATION,
          subj = Participant_ID,
          text_id = Text_ID,
          sent_id = Sentence_Number,
          word_idx = Word_In_Sentence_Number,
          word_text_idx = Word_Number,   # IA_ID?
          word = Word,      # Word?
          FPReg = IA_REGRESSION_OUT,
          skip = IA_SKIP,
          ff_progressive = IA_FIRST_FIX_PROGRESSIVE) %>%
  mutate(first_duration = gaze_duration) %>%
  mutate(gaze_duration = if_else(ff_progressive == 0, 0, as.double(gaze_duration)),
         go_past_time = if_else(ff_progressive == 0, 0, as.double(go_past_time))) %>%
  dplyr::select(-ff_progressive) %>%
  
  mutate(
    gaze_duration = if_else(total_duration == 0, 0, as.double(gaze_duration)),
      go_past_time = if_else(total_duration == 0, 0, as.double(go_past_time)),
      FPReg = if_else(total_duration == 0, -1, as.double(FPReg)),
      first_duration =  if_else(total_duration == 0, 0, as.double(first_duration)),
  ) %>%
  gather(metric, value, 7:12) %>%
  filter(value >= 0) %>%          # filter skipped word in eye tracking data for FPReg
  
  # ==== Remove skipped words
  mutate(zero = if_else(!metric %in% c("FPReg", "skip") & value == 0,T, F)) %>%
  filter(zero == F) %>%
  
  # mutate(value = if_else(is.na(value), as.integer(0), as.integer(value))) %>%
  # mutate(value = if_else(metric != "FPReg" & is.na(value), as.integer(0), as.integer(value))) %>%
  drop_na() %>%
  mutate(word = str_trim(word)) %>%
  mutate(subj = str_remove(subj, "Sub")) %>%
  mutate(subj = as.integer(subj)) %>%
    group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
  
  # === Remove outliers > 3SD
    # mutate(outlier = if_else(! metric %in% c("FPReg", "skip") & value > (mean(value) + 3 * sd(value) ), T, F)) %>%
    # filter(outlier == F) %>%
  
  ungroup() #%>%

# Aggregate cross-participant data for all subjects
provo_eyetracking_agg_df = provo_eyetracking_df %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value),
              nsubj = length(unique(subj))) %>%
    ungroup()
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
provo_raw_df %>%
  dplyr::select(IA_REGRESSION_OUT) %>%
  drop_na() %>%
  summarise( m = mean(IA_REGRESSION_OUT))

provo_raw_df %>%
  dplyr::select(IA_SKIP) %>%
  drop_na() %>%
  summarise( m = mean(IA_SKIP))
NA

# Split the eyetracking data in two by subjects to see how well it correlates with itself
provo_eyetracking_subj1_df_temp = provo_eyetracking_df %>%
  filter(subj <= 42) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value)) %>%
  ungroup() %>%
  rename(value_1 = value) #%>%
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
  # dplyr::select(-sent_id, -word_idx)


provo_eyetracking_subj1_df = merge(provo_eyetracking_subj1_df_temp, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
  arrange(text_id, sent_id, word_idx) %>%
  filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
  filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
  rename(word = word.y) %>%
  dplyr::select(text_id, word_text_idx, metric, word, value_1) 

# View(provo_eyetracking_subj1_df)

provo_eyetracking_subj2_df = provo_eyetracking_df %>%
  filter(subj > 42) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value)) %>%
  ungroup() %>%
    rename(value_2 = value)%>%
  dplyr::select(-sent_id, -word_idx)
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
# View(provo_eyetracking_subj2_df)
  
provo_eyetr_grouped_df = merge(provo_eyetracking_subj2_df, provo_eyetracking_subj1_df, by=c("text_id", "word_text_idx", "metric")) %>%
  # filter(word.x == word.y) %>%
  dplyr::select(-word.y) %>%
  # === Remove outliers > 3SD
  # group_by(metric) %>%
  #   mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_1 > (mean(value_1) + 3 * sd(value_1) ), T, F)) %>%
  #   filter(motr_outlier == F) %>%
  #   mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_2 > (mean(value_2) + 3 * sd(value_2) ), T, F)) %>%
  #   filter(eyetr_outlier == F) %>%
  # ungroup() %>%
  
  gather(measure, value, c("value_1", "value_2")) #%>%
  # dplyr::select(-motr_outlier, -eyetr_outlier)

# View(provo_eyetr_grouped_df)
provo_df = merge(provo_eyetracking_agg_df, provo_modeling_df, by=c("text_id", "sent_id", "word_idx")) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  arrange(text_id, sent_id, word_idx) %>%
  rename(eyetr_value = value) 

provo_df = merge(provo_df, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
arrange(text_id, sent_id, word_idx) %>%
  # almost all the word.x != word.y is because of normalization problem, so we can keep them, instead, deleting some special cases
filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
  filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
# filter(word.x == word) #%>%
dplyr::select(-word.x, -word.y) %>%
  
# === Remove outliers > 3SD
# group_by(metric) %>%
#   mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & motr_value > (mean(motr_value) + 3 * sd(motr_value) ), T, F)) %>%
#   filter(motr_outlier == F) %>%
#   mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & eyetr_value > (mean(eyetr_value) + 3 * sd(eyetr_value) ), T, F)) %>%
#   filter(eyetr_outlier == F) %>%
# ungroup() %>%
  
gather(measure, value, c("eyetr_value", "motr_value")) #%>%
# dplyr::select(-motr_outlier, -eyetr_outlier)
  
# provo_df

Bayesian – use Stan – motr & eyetr correlation

print("Gaze Duration")
[1] "Gaze Duration"
gd_df = provo_df %>% filter(metric == "gaze_duration") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(gd_df$eyetr_value, gd_df$motr_value)$estimate)
   cor 
0.4944 
print(cor.test(gd_df$eyetr_value_log, gd_df$motr_value_log)$estimate)
   cor 
0.5015 
# View(gd_df)
gd_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

NA
# center data around 0.

gd_temp <- gd_df[c("eyetr_value", "motr_value")] %>%
   # mutate(eyetr_value = eyetr_value - mean(eyetr_value),
   #      motr_value = motr_value - mean(motr_value)) %>%
  data.matrix()

gd_temp_log <- gd_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(gd_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix gd_temp_log
plot(gd_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

gd_data = list(x=gd_temp, N=nrow(gd_temp))

fit_gd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=gd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_gd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gd, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds"))
print("Go Past Time")
[1] "Go Past Time"
gpt_df = provo_df %>% filter(metric == "go_past_time") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(gpt_df$eyetr_value, gpt_df$motr_value)$estimate)
   cor 
0.5122 
print(cor.test(gpt_df$eyetr_value_log, gpt_df$motr_value_log)$estimate)
   cor 
0.4607 
gpt_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

gpt_temp <- gpt_df[c("eyetr_value", "motr_value")] %>% data.matrix()

gpt_temp_log <- gpt_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gpt_temp
plot(gpt_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix gpt_temp_log
plot(gpt_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

# -------fit model go past time ----------
gpt_data = list(x=gpt_temp, N=nrow(gpt_temp))
fit_gpt = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=gpt_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_gpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gpt, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds"))
print("Total Duration")
[1] "Total Duration"
td_df = provo_df %>% filter(metric == "total_duration") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(td_df$eyetr_value, td_df$motr_value)$estimate)
   cor 
0.5952 
print(cor.test(td_df$eyetr_value_log, td_df$motr_value_log)$estimate)
   cor 
0.5957 
td_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

td_temp <- td_df[c("eyetr_value", "motr_value")] %>% data.matrix()

td_temp_log <- td_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(td_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix td_temp_log
plot(td_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

# -------fit model total duration ----------
td_data = list(x=td_temp, N=nrow(td_temp))
fit_td = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=td_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_td@stanmodel@dso <- new("cxxdso")
saveRDS(fit_td, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds"))
print("First Pass Regression Prob.")
[1] "First Pass Regression Prob."
reg_df = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5))
print(cor.test(reg_df$eyetr_value, reg_df$motr_value)$estimate)
  cor 
0.386 
# View(reg_df)
reg_df %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp <- reg_df[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

# -------fit model FPReg ----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
  file="stan_models/bivariate_normal_reg.stan", 
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds"))

rank transformation for FPReg

reg_df = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  mutate(
    eyetr_value_rank = ifelse(eyetr_value > 0, rank(eyetr_value), NA),
    motr_value_rank = ifelse(motr_value > 0, rank(motr_value), NA)
  ) %>%
  drop_na()
#   mutate(
#   eyetr_value_rank = rank(eyetr_value, ties.method = "average"),
#   motr_value_rank = rank(motr_value, ties.method = "average")
# )
# View(reg_df)

print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank)$estimate)
print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank, method = "kendall"))


reg_df %>% 
  gather(measure, value, 14:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp <- reg_df[c("eyetr_value_rank", "motr_value_rank")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
     main = "Rank Transformed")
# -------fit model FPReg RANK----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
  file="stan_models/bivariate_correlation_rank.stan", 
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds"))
print("skip Prob.")
[1] "skip Prob."
skip_df = provo_df %>% filter(metric == "skip") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5))
print(cor.test(skip_df$eyetr_value, skip_df$motr_value)$estimate)
   cor 
0.7945 
# View(reg_df)
skip_df %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

skip_temp <- skip_df[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(skip_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

# -------fit model skip ----------
skip_data = list(x=skip_temp, N=nrow(skip_temp))
fit_skip = stan(
  file="stan_models/bivariate_normal_reg.stan", 
  data=skip_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_skip@stanmodel@dso <- new("cxxdso")
saveRDS(fit_skip, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_skip_cor_drop0s.rds"))
fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds")
fit_reg_rank = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds")
fit_skip = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_skip_cor_drop0s.rds")

# models for drop 0s
# fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
# fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
# fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
# fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/ranked_motr_eyetr_FPReg_cor.rds")

print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_gd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           234.30    0.01   0.90    232.53    233.69    234.29    234.91    236.06  6945    1
mu[2]           371.77    0.02   1.74    368.30    370.63    371.77    372.91    375.24  6640    1
sigma[1]         37.80    0.01   0.81     36.24     37.26     37.79     38.34     39.42  5283    1
sigma[2]         71.83    0.02   1.46     69.03     70.82     71.83     72.82     74.71  5227    1
nu                4.46    0.00   0.30      3.92      4.25      4.45      4.65      5.08  5469    1
rho               0.51    0.00   0.02      0.48      0.50      0.51      0.52      0.54  6947    1
cov[1,1]       1429.34    0.84  61.16   1313.63   1388.16   1427.81   1469.75   1553.95  5276    1
cov[1,2]       1391.14    1.15  78.47   1239.24   1339.15   1390.35   1441.79   1551.58  4667    1
cov[2,1]       1391.14    1.15  78.47   1239.24   1339.15   1390.35   1441.79   1551.58  4667    1
cov[2,2]       5161.37    2.91 210.40   4765.32   5015.23   5159.80   5302.57   5580.95  5231    1
x_rand[1]       235.01    0.55  49.34    138.86    206.52    234.61    262.42    336.83  8089    1
x_rand[2]       373.62    1.07  95.15    182.83    319.23    372.21    425.30    567.12  7980    1
attempt           0.00    0.00   0.05      0.00      0.00      0.00      0.00      0.00  8050    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -25082.82    0.03   1.80 -25087.41 -25083.73 -25082.46 -25081.52 -25080.40  3875    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:04:08 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_gpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%      25%       50%       75%     97.5% n_eff Rhat
mu[1]           306.99    0.02   1.71    303.61    305.9    306.97    308.14    310.35  8255    1
mu[2]           425.10    0.03   2.96    419.39    423.0    425.10    427.11    430.79  8294    1
sigma[1]         67.11    0.02   1.47     64.27     66.1     67.10     68.10     70.03  7296    1
sigma[2]        116.24    0.03   2.64    111.16    114.5    116.21    118.01    121.46  7232    1
nu                2.26    0.00   0.09      2.08      2.2      2.26      2.32      2.45  7418    1
rho               0.42    0.00   0.02      0.38      0.4      0.42      0.43      0.45  8786    1
cov[1,1]       4505.28    2.31 197.26   4130.64   4369.6   4501.91   4637.37   4904.27  7307    1
cov[1,2]       3248.81    2.51 213.71   2842.87   3101.4   3244.96   3391.94   3668.78  7277    1
cov[2,1]       3248.81    2.51 213.71   2842.87   3101.4   3244.96   3391.94   3668.78  7277    1
cov[2,2]      13517.55    7.22 613.53  12357.23  13097.8  13505.59  13925.78  14752.13  7226    1
x_rand[1]       318.77    1.49 134.42    121.89    258.4    309.38    363.21    564.06  8092    1
x_rand[2]       451.19    3.26 294.27    111.69    344.8    430.62    522.20    876.86  8131    1
attempt           0.04    0.00   0.21      0.00      0.0      0.00      0.00      1.00  8093    1
max_attempts     10.00     NaN   0.00     10.00     10.0     10.00     10.00     10.00   NaN  NaN
lp__         -29010.67    0.03   1.76 -29015.10 -29011.6 -29010.35 -29009.40 -29008.25  3994    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:05:58 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_td)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           266.87    0.02   1.28    264.39    266.01    266.86    267.75    269.33  5448    1
mu[2]           420.80    0.03   2.46    416.02    419.15    420.76    422.47    425.53  5573    1
sigma[1]         52.62    0.02   1.10     50.47     51.88     52.61     53.36     54.78  4500    1
sigma[2]        100.49    0.03   2.03     96.58     99.11    100.48    101.84    104.53  4579    1
nu                4.28    0.00   0.27      3.79      4.09      4.27      4.46      4.85  5361    1
rho               0.62    0.00   0.01      0.59      0.61      0.62      0.63      0.65  6752    1
cov[1,1]       2769.92    1.73 115.77   2547.56   2691.20   2768.16   2846.87   3000.64  4498    1
cov[1,2]       3278.82    2.57 164.70   2966.61   3164.38   3277.56   3386.73   3608.01  4100    1
cov[2,1]       3278.82    2.57 164.70   2966.61   3164.38   3277.56   3386.73   3608.01  4100    1
cov[2,2]      10102.99    6.04 408.74   9326.88   9822.79  10095.99  10371.05  10925.76  4584    1
x_rand[1]       268.11    0.79  69.98    127.37    228.67    268.19    306.65    407.71  7859    1
x_rand[2]       427.30    1.52 133.15    166.09    351.69    423.23    498.89    698.02  7666    1
attempt           0.01    0.00   0.09      0.00      0.00      0.00      0.00      0.00  8123    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -26591.96    0.03   1.74 -26596.19 -26592.83 -26591.63 -26590.69 -26589.56  3343    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:07:59 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_reg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.14    0.00 0.00    0.13    0.14    0.14    0.14    0.14  8022    1
mu[2]           0.09    0.00 0.00    0.08    0.08    0.09    0.09    0.09  8135    1
sigma[1]        0.08    0.00 0.00    0.08    0.08    0.08    0.08    0.09  7142    1
sigma[2]        0.05    0.00 0.00    0.04    0.05    0.05    0.05    0.05  7221    1
nu              2.78    0.00 0.18    2.46    2.65    2.77    2.89    3.14  7451    1
rho             0.21    0.00 0.03    0.16    0.19    0.21    0.23    0.27  9921    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  7143    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8463    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8463    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7208    1
x_rand[1]       0.17    0.00 0.13    0.02    0.10    0.15    0.21    0.42  7885    1
x_rand[2]       0.10    0.00 0.07    0.01    0.06    0.09    0.12    0.25  7935    1
attempt         0.17    0.01 0.46    0.00    0.00    0.00    0.00    1.00  7711    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         4545.35    0.03 1.75 4541.07 4544.43 4545.68 4546.62 4547.74  3653    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:09:17 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. RANK--------------------------------------------"
print(fit_reg_rank)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean       sd      2.5%       25%       50%      75%     97.5% n_eff Rhat
mu[1]          1374.90    0.18    18.98   1337.48   1362.16   1374.73   1387.9   1411.91 11231    1
mu[2]          1804.27    0.11    11.31   1782.23   1796.66   1804.43   1811.9   1826.26 10240    1
sigma[1]        696.99    0.12    12.87    672.39    688.36    696.94    705.4    723.03 10941    1
sigma[2]        418.96    0.08     7.84    403.87    413.54    418.83    424.2    434.92 10853    1
nu              102.55    0.23    23.98     63.02     85.64    100.14    116.5    157.44 10504    1
rho               0.19    0.00     0.03      0.14      0.17      0.19      0.2      0.24 11138    1
cov[1,1]     485954.71  172.11 17956.82 452113.94 473835.62 485723.58 497595.5 522770.76 10885    1
cov[1,2]      54509.75   75.79  7861.98  39206.85  49139.03  54379.02  59723.2  70306.93 10762    1
cov[2,1]      54509.75   75.79  7861.98  39206.85  49139.03  54379.02  59723.2  70306.93 10762    1
cov[2,2]     175589.65   63.18  6576.69 163113.47 171011.52 175420.06 179976.5 189159.61 10834    1
x_rand[1]      1420.17    7.48   659.95    217.73    942.20   1404.35   1864.0   2767.59  7778    1
x_rand[2]      1804.04    4.94   427.24    964.46   1521.76   1803.44   2090.0   2641.59  7493    1
attempt           0.03    0.00     0.18      0.00      0.00      0.00      0.0      1.00  8072    1
max_attempts     10.00     NaN     0.00     10.00     10.00     10.00     10.0     10.00   NaN  NaN
lp__         -20329.53    0.03     1.75 -20333.76 -20330.49 -20329.20 -20328.2 -20327.15  4066    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:12:53 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Skip Prob.--------------------------------------------')
[1] "---------------------------- Skip Prob.--------------------------------------------"
print(fit_skip)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean    sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.44    0.00  0.00    0.43    0.44    0.44    0.44    0.45  5294    1
mu[2]           0.46    0.00  0.01    0.45    0.45    0.46    0.46    0.47  5320    1
sigma[1]        0.22    0.00  0.00    0.22    0.22    0.22    0.23    0.23  4893    1
sigma[2]        0.25    0.00  0.00    0.24    0.25    0.25    0.25    0.25  5030    1
nu            100.97    0.26 23.54   62.68   84.28   98.17  115.01  154.51  7911    1
rho             0.80    0.00  0.01    0.78    0.79    0.80    0.80    0.81  5412    1
cov[1,1]        0.05    0.00  0.00    0.05    0.05    0.05    0.05    0.05  4891    1
cov[1,2]        0.04    0.00  0.00    0.04    0.04    0.04    0.05    0.05  4075    1
cov[2,1]        0.04    0.00  0.00    0.04    0.04    0.04    0.05    0.05  4075    1
cov[2,2]        0.06    0.00  0.00    0.06    0.06    0.06    0.06    0.06  5025    1
x_rand[1]       0.46    0.00  0.20    0.09    0.32    0.46    0.60    0.89  7796    1
x_rand[2]       0.48    0.00  0.23    0.08    0.32    0.47    0.63    0.96  7592    1
attempt         0.05    0.00  0.21    0.00    0.00    0.00    0.00    1.00  7949    1
max_attempts   10.00     NaN  0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         4253.99    0.03  1.75 4249.74 4253.06 4254.32 4255.27 4256.38  3625    1

Samples were drawn using NUTS(diag_e) at Sun Feb 25 01:27:44 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# stan_trace(fit_gd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_gd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_gd, pars=c("rho", "mu", "sigma", "nu"))

# Gaze Duration
stan_trace(fit_gd)
stan_dens(fit_gd, separate_chains = TRUE)
stan_plot(fit_gd)

# Go Past Time
stan_trace(fit_gpt)
stan_dens(fit_gpt, separate_chains = TRUE)
stan_plot(fit_gpt)

# Total Duration
stan_trace(fit_td)
stan_dens(fit_td, separate_chains = TRUE)
stan_plot(fit_td)

# FPReg
stan_trace(fit_reg)
stan_dens(fit_reg, separate_chains = TRUE)
stan_plot(fit_reg)
p1 <- stan_trace(fit_gd, pars = 'rho', inc_warmup = FALSE)
p2 <- stan_dens(fit_gd, pars = 'rho', separate_chains = TRUE)
p3 <- stan_trace(fit_gd, pars = 'mu[1]', inc_warmup = FALSE)
p4 <- stan_dens(fit_gd, pars = 'mu[1]', separate_chains = TRUE)
p5 <- stan_trace(fit_gd, pars = 'mu[2]', inc_warmup = FALSE)
p6 <- stan_dens(fit_gd, pars = 'mu[2]', separate_chains = TRUE)
p7 <- stan_trace(fit_gd, pars = 'sigma[1]', inc_warmup = FALSE)
p8 <- stan_dens(fit_gd, pars = 'sigma[1]', separate_chains = TRUE)
p9 <- stan_trace(fit_gd, pars = 'sigma[2]', inc_warmup = FALSE)
p10 <- stan_dens(fit_gd, pars = 'sigma[2]', separate_chains = TRUE)
p11 <- stan_trace(fit_gd, pars = 'nu', inc_warmup = FALSE)
p12 <- stan_dens(fit_gd, pars = 'nu', separate_chains = TRUE)


# Use grid.arrange() to arrange the plots
# grid.arrange(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, ncol=2, nrow=6)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_gd = as.numeric(extract(fit_gd, "rho")[[1]])
mean = mean(rho_gd)
crI = quantile(rho_gd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.5121
HPD: [0.4784, 0.5441]
crI: [0.4789, 0.5448]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_gpt = as.numeric(extract(fit_gpt, "rho")[[1]])
mean = mean(rho_gpt)
crI = quantile(rho_gpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4163
HPD: [0.3793, 0.455]
crI: [0.378, 0.4539]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_td = as.numeric(extract(fit_td, "rho")[[1]])
mean = mean(rho_td)
crI = quantile(rho_td, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_td), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6197
HPD: [0.5915, 0.6471]
crI: [0.5912, 0.647]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.2139
HPD: [0.1561, 0.2715]
crI: [0.1554, 0.2711]
print('---------------------------- First Pass Regression RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression RANK--------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg_rank, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.1866
HPD: [0.1359, 0.2356]
crI: [0.1367, 0.2367]
print('---------------------------- Skip --------------------------------------------')
[1] "---------------------------- Skip --------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_skip = as.numeric(extract(fit_skip, "rho")[[1]])
mean = mean(rho_skip)
crI = quantile(rho_skip, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_skip), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.7975
HPD: [0.7823, 0.8112]
crI: [0.7827, 0.8117]
print('---------------------------- Gaze Duration--------------------------------------------')
gd_rand <- extract(fit_gd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(gd_rand[,1], gd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(gd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Go Past Time--------------------------------------------')
gpt_rand <- extract(fit_gpt, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(gpt_rand[,1], gpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gpt_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(gpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Total Duration--------------------------------------------')
td_rand <- extract(fit_td, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Total Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(td_rand[,1], td_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(td_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(td_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(td_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression --------------------------------------------')
reg_rand <- extract(fit_reg, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(reg_rand[,1], reg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(reg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(reg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Skip --------------------------------------------')
skip_rand <- extract(fit_skip, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Skip") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(skip_rand[,1], skip_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(skip_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(skip_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(skip_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

model motr eyetr FPReg correlation (eyetr < 0.3)

print("First Pass Regression Prob. all and  < 0.3")
[1] "First Pass Regression Prob. all and  < 0.3"
reg_df_all = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5))

reg_df_low_drop0 = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value < 0.3)

reg_df_low = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value < 0.3)
  # mutate(eyetr_value = exp(eyetr_value),
         # motr_value = exp(motr_value)
         # )
# View(reg_df)

print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$estimate)
   cor 
0.3024 
print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$p.value)
[1] 0.000000000000000000000000000000000000000000000000000000915
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$estimate)
   cor 
0.1071 
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$p.value)
[1] 0.000000334
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$estimate)
    cor 
0.08719 
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$p.value)
[1] 0.002145
# View(reg_df)
reg_df_low %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp_all <- reg_df_all[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low <- reg_df_low[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low_drop0 <- reg_df_low_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp_low, pch = 16, col = "blue",
     main = "Not Log-Transformed")

# -------fit model FPReg < 0.3 ----------
reg_data = list(x=reg_temp_all, N=nrow(reg_temp_all))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_all_data_drop0s.rds"))

model motr eyetr FPReg correlation (eyetr >= 0.3)

print("First Pass Regression Prob. >= 0.3")
[1] "First Pass Regression Prob. >= 0.3"
reg_df_high_drop0 = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value >= 0.3)

reg_df_high = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value >= 0.3)
  # mutate(eyetr_value = exp(eyetr_value),
         # motr_value = exp(motr_value)
         # )
# View(reg_df)

print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$estimate)
   cor 
0.4202 
print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$p.value)
[1] 0.0000000000002819
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$estimate)
   cor 
0.4904 
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$p.value)
[1] 0.0000000000012
# View(reg_df)
reg_df_high %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp_high <- reg_df_high[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_high_drop0 <- reg_df_high_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))

# Plot the first data matrix td_temp
plot(reg_temp_all, pch = 16, col = "blue",
     main = "FPReg not logged all data")
plot(reg_temp_low, pch = 16, col = "blue",
     main = "FPReg not logged eyetr < 0.3 ")
plot(reg_temp_high, pch = 16, col = "blue",
     main = "FPReg not logged eyetr >= 0.3")

# -------fit model FPReg >= 0.3 ----------
reg_data = list(x=reg_temp_high_drop0, N=nrow(reg_temp_high_drop0))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0(".//bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_03-1_drop0s.rds"))
fit_mreg_all = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data.rds")
fit_mreg_all_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data_drop0s.rds")
fit_mreg_low = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03.rds")
fit_mreg_low_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03_drop0s.rds")
fit_mreg_high = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1.rds")
fit_mreg_high_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1_drop0s.rds")

print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data --------------------------------------------"
print(fit_mreg_all)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.12    0.00 0.00    0.12    0.12    0.12    0.13    0.13  5811    1
mu[2]           0.03    0.00 0.00    0.02    0.03    0.03    0.03    0.03  3384    1
sigma[1]        0.08    0.00 0.00    0.07    0.07    0.08    0.08    0.08  3694    1
sigma[2]        0.05    0.00 0.00    0.05    0.05    0.05    0.05    0.06  3040    1
nu              2.42    0.00 0.14    2.16    2.33    2.42    2.52    2.71  3250    1
rho             0.16    0.00 0.02    0.11    0.14    0.16    0.17    0.20  8176    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3693    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6348    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6348    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  3053    1
x_rand[1]       0.16    0.00 0.12    0.02    0.09    0.14    0.20    0.40  7811    1
x_rand[2]       0.07    0.00 0.08    0.00    0.03    0.05    0.09    0.25  7966    1
attempt         0.63    0.01 1.03    0.00    0.00    0.00    1.00    3.00  7919    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         7450.58    0.03 1.78 7446.22 7449.65 7450.92 7451.89 7452.98  3519    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 23:08:09 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------"
print(fit_mreg_all_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.15    0.00 0.00    0.14    0.15    0.15    0.15    0.16  8507    1
mu[2]           0.14    0.00 0.00    0.13    0.14    0.14    0.14    0.14  7923    1
sigma[1]        0.09    0.00 0.00    0.08    0.08    0.09    0.09    0.09  7186    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.06  6227    1
nu              2.78    0.00 0.23    2.37    2.62    2.77    2.93    3.26  7008    1
rho             0.18    0.00 0.04    0.11    0.16    0.18    0.21    0.26  9833    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  7173    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8599    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8599    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6234    1
x_rand[1]       0.18    0.00 0.13    0.02    0.10    0.16    0.22    0.43  7699    1
x_rand[2]       0.15    0.00 0.08    0.03    0.10    0.14    0.18    0.34  8175    1
attempt         0.16    0.00 0.43    0.00    0.00    0.00    0.00    1.00  7917    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         2566.44    0.03 1.75 2562.18 2565.53 2566.76 2567.72 2568.88  3487    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 23:18:11 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------"
print(fit_mreg_low)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.12    0.00 0.00    0.11    0.12    0.12    0.12    0.12  8566    1
mu[2]           0.03    0.00 0.00    0.03    0.03    0.03    0.04    0.04  4981    1
sigma[1]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  7280    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  4552    1
nu              5.54    0.01 0.51    4.62    5.19    5.51    5.86    6.62  4637    1
rho             0.10    0.00 0.02    0.06    0.09    0.10    0.12    0.15  8596    1
cov[1,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7299    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8259    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8259    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  4571    1
x_rand[1]       0.13    0.00 0.07    0.02    0.08    0.12    0.17    0.28  8277    1
x_rand[2]       0.07    0.00 0.06    0.00    0.03    0.06    0.10    0.21  7280    1
attempt         0.53    0.01 0.90    0.00    0.00    0.00    1.00    3.00  8006    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         7794.82    0.03 1.78 7790.50 7793.88 7795.16 7796.13 7797.26  3232    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 20:52:03 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------"
print(fit_mreg_low_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.13    0.00 0.00    0.13    0.13    0.13    0.13    0.14 10534    1
mu[2]           0.13    0.00 0.00    0.13    0.13    0.13    0.14    0.14  8839    1
sigma[1]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  8534    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.07    0.07  7122    1
nu              6.50    0.01 0.96    4.90    5.83    6.40    7.06    8.73  6790    1
rho             0.07    0.00 0.04    0.00    0.05    0.07    0.10    0.15 10356    1
cov[1,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8526    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00 10435    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00 10435    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7123    1
x_rand[1]       0.14    0.00 0.07    0.02    0.09    0.13    0.18    0.28  8031    1
x_rand[2]       0.14    0.00 0.07    0.02    0.10    0.14    0.18    0.29  8006    1
attempt         0.08    0.00 0.30    0.00    0.00    0.00    0.00    1.00  7642    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         2737.21    0.03 1.76 2732.81 2736.27 2737.56 2738.50 2739.62  3992    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 20:30:02 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------"
print(fit_mreg_high)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

               mean se_mean    sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
mu[1]          0.45    0.00  0.01   0.44   0.45   0.45   0.46   0.47  5045    1
mu[2]          0.15    0.00  0.01   0.13   0.15   0.15   0.16   0.18  4628    1
sigma[1]       0.11    0.00  0.01   0.10   0.11   0.11   0.12   0.12  5622    1
sigma[2]       0.15    0.00  0.01   0.13   0.15   0.15   0.16   0.17  4499    1
nu            25.71    0.18 12.83   9.59  16.53  22.89  31.70  58.03  5109    1
rho            0.41    0.00  0.06   0.30   0.37   0.41   0.45   0.51  7137    1
cov[1,1]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5625    1
cov[1,2]       0.01    0.00  0.00   0.00   0.01   0.01   0.01   0.01  4842    1
cov[2,1]       0.01    0.00  0.00   0.00   0.01   0.01   0.01   0.01  4842    1
cov[2,2]       0.02    0.00  0.00   0.02   0.02   0.02   0.03   0.03  4553    1
x_rand[1]      0.47    0.00  0.11   0.25   0.39   0.47   0.54   0.70  7964    1
x_rand[2]      0.20    0.00  0.13   0.01   0.10   0.19   0.28   0.49  7829    1
attempt        0.19    0.01  0.47   0.00   0.00   0.00   0.00   1.00  7881    1
max_attempts  10.00     NaN  0.00  10.00  10.00  10.00  10.00  10.00   NaN  NaN
lp__         579.26    0.03  1.75 575.10 578.35 579.56 580.56 581.68  3529    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 22:25:38 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------"
print(fit_mreg_high_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

               mean se_mean    sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
mu[1]          0.48    0.00  0.01   0.46   0.48   0.48   0.49   0.51  6409    1
mu[2]          0.27    0.00  0.01   0.25   0.26   0.27   0.28   0.30  6397    1
sigma[1]       0.12    0.00  0.01   0.11   0.12   0.12   0.13   0.14  6555    1
sigma[2]       0.16    0.00  0.01   0.14   0.15   0.16   0.17   0.18  6281    1
nu            32.85    0.16 15.27  11.84  21.65  30.12  40.80  69.54  8953    1
rho            0.51    0.00  0.07   0.37   0.47   0.52   0.56   0.64  6986    1
cov[1,1]       0.02    0.00  0.00   0.01   0.01   0.02   0.02   0.02  6491    1
cov[1,2]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5145    1
cov[2,1]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5145    1
cov[2,2]       0.03    0.00  0.00   0.02   0.02   0.03   0.03   0.03  6242    1
x_rand[1]      0.49    0.00  0.13   0.25   0.41   0.49   0.57   0.74  8129    1
x_rand[2]      0.29    0.00  0.15   0.04   0.18   0.28   0.38   0.60  7467    1
attempt        0.06    0.00  0.24   0.00   0.00   0.00   0.00   1.00  7913    1
max_attempts  10.00     NaN  0.00  10.00  10.00  10.00  10.00  10.00   NaN  NaN
lp__         300.28    0.03  1.75 296.05 299.35 300.60 301.58 302.70  3555    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 22:31:08 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# # FPReg all data
# stan_trace(fit_mreg_all)
# stan_dens(fit_mreg_all, separate_chains = TRUE)
# stan_plot(fit_mreg_all)

# stan_trace(fit_mreg_all_drop0)
# stan_dens(fit_mreg_all_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_all_drop0)

# # FPReg < 0.3
# stan_trace(fit_mreg_low)
# stan_dens(fit_mreg_low, separate_chains = TRUE)
# stan_plot(fit_mreg_low)
# 
# stan_trace(fit_mreg_low_drop0)
# stan_dens(fit_mreg_low_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_low_drop0)

# FPReg > 0.3
stan_trace(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

stan_trace(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high_drop0, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

print('---------------------------- First Pass Regression all data--------------------------------------------')
[1] "---------------------------- First Pass Regression all data--------------------------------------------"
rho_mreg_all = as.numeric(extract(fit_mreg_all, "rho")[[1]])
mean = mean(rho_mreg_all)
crI = quantile(rho_mreg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1574
HPD: [0.1139, 0.2017]
crI: [0.1134, 0.2014]
print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression all data no 0s--------------------------------------------"
rho_mreg_all_drop0 = as.numeric(extract(fit_mreg_all_drop0, "rho")[[1]])
mean = mean(rho_mreg_all_drop0)
crI = quantile(rho_mreg_all_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1843
HPD: [0.1106, 0.2573]
crI: [0.1114, 0.2581]
print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3--------------------------------------------"
rho_mreg_low = as.numeric(extract(fit_mreg_low, "rho")[[1]])
mean = mean(rho_mreg_low)
crI = quantile(rho_mreg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.103
HPD: [0.05775, 0.1468]
crI: [0.05805, 0.1475]
print('---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------"
rho_mreg_low_drop0 = as.numeric(extract(fit_mreg_low_drop0, "rho")[[1]])
mean = mean(rho_mreg_low_drop0)
crI = quantile(rho_mreg_low_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.07362
HPD: [-0.000616, 0.1514]
crI: [-0.003759, 0.1491]
print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3--------------------------------------------"
rho_mreg_high = as.numeric(extract(fit_mreg_high, "rho")[[1]])
mean = mean(rho_mreg_high)
crI = quantile(rho_mreg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4102
HPD: [0.3001, 0.5155]
crI: [0.2992, 0.5146]
print('---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------"
rho_mreg_high_drop0 = as.numeric(extract(fit_mreg_high_drop0, "rho")[[1]])
mean = mean(rho_mreg_high_drop0)
crI = quantile(rho_mreg_high_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.514
HPD: [0.3797, 0.6456]
crI: [0.3728, 0.6412]
print('---------------------------- First Pass Regression all data --------------------------------------------')
mallreg_rand <- extract(fit_mreg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mallreg_rand[,1], mallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
mallreg_rand_drop0 <- extract(fit_mreg_all_drop0, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mallreg_rand_drop0[,1], mallreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mallreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
mlowreg_rand <- extract(fit_mreg_low, "x_rand")[[1]]
print(mlowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlowreg_rand[,1], mlowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 no 0s --------------------------------------------')
mlowreg_rand_drop0 <- extract(fit_mreg_low_drop0, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlowreg_rand_drop0[,1], mlowreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low_drop0, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlowreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
mhighreg_rand_samples <- extract(fit_mreg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(mhighreg_rand_samples), 900)
mhighreg_rand <- mhighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mhighreg_rand[,1], mhighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mhighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

# print('---------------------------- First Pass Regression >= 0.3 no 0s --------------------------------------------')
mhighreg_rand_drop0_samples <- extract(fit_mreg_high_drop0, "x_rand")[[1]]
selected_indices <- sample(1:nrow(mhighreg_rand_drop0_samples), 900)
mhighreg_rand_drop0 <- mhighreg_rand_drop0_samples[selected_indices, ]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color
points(mhighreg_rand_drop0[,1], mhighreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high_drop0, pch=16, col="red")

# add dataEllipse with color
dataEllipse(mhighreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

model eye tracking to eye tracking correlation


print("Gaze Duration")
[1] "Gaze Duration"
# View(provo_eyetr_grouped_df)

egd_df = provo_eyetr_grouped_df %>% filter(metric == "gaze_duration") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
    filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(egd_df$eyetr_value_1, egd_df$eyetr_value_2)$estimate)
  cor 
0.767 
# View(egd_df)

egd_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

egd_temp <- egd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egd_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

egd_data = list(x=egd_temp, N=nrow(egd_temp))

fit_egd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=egd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_egd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egd, file = paste0("./bayesian_models/bayesian_models_correlation/cor_bivariate/eyetr_eyetr_gaze_duration_cor.rds"))
print("Go Past Time")
[1] "Go Past Time"
egpt_df = provo_eyetr_grouped_df %>% filter(metric == "go_past_time") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(egpt_df$eyetr_value_1, egpt_df$eyetr_value_2)$estimate)
   cor 
0.5582 
# View(egd_df)

egpt_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

egpt_temp <- egpt_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egpt_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

egpt_data = list(x=egpt_temp, N=nrow(egpt_temp))

fit_egpt = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=egpt_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_egpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egpt, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor.rds"))
print("Total Duration")
[1] "Total Duration"
etd_df = provo_eyetr_grouped_df %>% filter(metric == "total_duration") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(etd_df$eyetr_value_1, etd_df$eyetr_value_2)$estimate)
   cor 
0.8341 
# View(egd_df)

etd_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

etd_temp <- etd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(etd_temp, pch = 16, col = "blue",
     main = "Total Duration Not Log-Transformed")

etd_data = list(x=etd_temp, N=nrow(etd_temp))

fit_etd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=etd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_etd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_etd, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor.rds"))
print("Fisrt Pass Regression Prob.")
[1] "Fisrt Pass Regression Prob."
ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  # filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  
  # ==== for normal data drop0s ====
  # filter(value_1 > 0, value_2 > 0) %>%
  # mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
  #        eyetr_value_2 = pmax(value_2, 1e-5)
  # )
  
  # ==== for ranking the data drop0s ====
    mutate(
    eyetr_value_1 = ifelse(value_1 > 0, rank(value_1), NA),
    eyetr_value_2 = ifelse(value_2 > 0, rank(value_2), NA)
  ) %>%
  drop_na()

  # ==== for ranking the data w/ 0s ====
  #   mutate(
  #   eyetr_value_1 = rank(value_1, ties.method = "average"),
  #   eyetr_value_2 = rank(value_2, ties.method = "average")
  # )


print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
   cor 
0.5809 
# View(egd_df)

ereg_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
     main = "FPReg Not Log-Transformed")

# -------fit model FPReg ----------

# View(ereg_temp)
ereg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_ereg = stan(
  file="stan_models/bivariate_correlation_rank.stan", 
  data=ereg_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99),
  verbose = FALSE
  )

# Save the model 
fit_ereg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_ereg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_rank_drop0s.rds"))
print("Skip Prob.")
[1] "Skip Prob."
eskip_df = provo_eyetr_grouped_df %>% filter(metric == "skip") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  # filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
  filter(text_id != 18) %>%
    spread(measure, value)
  
  # ==== for normal data drop0s ====
  # filter(value_1 > 0, value_2 > 0) %>%
  # mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
  #        eyetr_value_2 = pmax(value_2, 1e-5)
  # )
  
  # ==== for ranking the data drop0s ====
  #   mutate(
  #   eyetr_value_1 = ifelse(value_1 > 0, rank(value_1), NA),
  #   eyetr_value_2 = ifelse(value_2 > 0, rank(value_2), NA)
  # ) %>%
  # drop_na()

  # ==== for ranking the data w/ 0s ====
  #   mutate(
  #   eyetr_value_1 = rank(value_1, ties.method = "average"),
  #   eyetr_value_2 = rank(value_2, ties.method = "average")
  # )


print(cor.test(eskip_df$value_1, eskip_df$value_2)$estimate)
   cor 
0.9073 
eskip_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

eskip_temp <- eskip_df[c("value_1", "value_2")] %>%
  drop_na() %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(eskip_temp, pch = 16, col = "blue",
     main = "Skip Not Log-Transformed")

# -------fit model Skip ----------

# View(ereg_temp)
eskip_data = list(x=eskip_temp, N=nrow(eskip_temp))
fit_eskip = stan(
  file="stan_models/bivariate_normal_reg.stan", 
  data=eskip_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99),
  verbose = FALSE
  )

# Save the model 
fit_eskip@stanmodel@dso <- new("cxxdso")
saveRDS(fit_eskip, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_skip_cor_drop0s.rds"))
fit_egd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_gaze_duration_cor_drop0s.rds")
fit_egpt = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor_drop0s.rds")
fit_etd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor_drop0s.rds")
fit_ereg = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_drop0s.rds")
fit_eskip = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_skip_cor_drop0s.rds")
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_egd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean    sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           234.21    0.01  1.00    232.27    233.54    234.19    234.87    236.20  4635    1
mu[2]           236.90    0.01  0.97    235.02    236.24    236.90    237.54    238.79  4910    1
sigma[1]         41.69    0.02  0.91     39.91     41.08     41.68     42.29     43.51  3619    1
sigma[2]         40.43    0.01  0.85     38.80     39.85     40.42     41.00     42.11  3582    1
nu                4.79    0.01  0.34      4.18      4.55      4.77      5.01      5.49  4490    1
rho               0.75    0.00  0.01      0.73      0.74      0.75      0.75      0.77  5064    1
cov[1,1]       1738.83    1.26 75.69   1593.04   1687.35   1737.16   1788.84   1892.83  3618    1
cov[1,2]       1261.40    1.07 60.61   1144.60   1219.78   1259.97   1301.33   1383.64  3231    1
cov[2,1]       1261.40    1.07 60.61   1144.60   1219.78   1259.97   1301.33   1383.64  3231    1
cov[2,2]       1635.31    1.15 68.73   1505.18   1588.13   1633.89   1680.99   1772.85  3581    1
x_rand[1]       235.04    0.60 53.55    126.81    204.21    234.45    265.21    343.46  8071    1
x_rand[2]       238.08    0.58 52.25    134.49    207.68    237.12    267.21    343.68  8199    1
attempt           0.00    0.00  0.06      0.00      0.00      0.00      0.00      0.00  7607    1
max_attempts     10.00     NaN  0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -22639.73    0.03  1.75 -22644.12 -22640.68 -22639.40 -22638.44 -22637.35  3653    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:34:23 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_egpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           303.70    0.03   2.02    299.63    302.37    303.70    305.04    307.61  6230    1
mu[2]           302.11    0.02   1.80    298.65    300.89    302.10    303.33    305.69  6262    1
sigma[1]         77.62    0.03   1.77     74.18     76.42     77.61     78.81     81.07  4594    1
sigma[2]         68.55    0.02   1.51     65.64     67.52     68.54     69.56     71.58  4950    1
nu                2.33    0.00   0.10      2.13      2.25      2.32      2.40      2.53  5695    1
rho               0.63    0.00   0.01      0.60      0.62      0.63      0.64      0.66  7305    1
cov[1,1]       6028.02    4.05 274.38   5502.89   5840.25   6022.79   6211.77   6572.65  4595    1
cov[1,2]       3372.29    2.65 178.45   3030.75   3248.64   3367.12   3492.40   3732.72  4544    1
cov[2,1]       3372.29    2.65 178.45   3030.75   3248.64   3367.12   3492.40   3732.72  4544    1
cov[2,2]       4701.89    2.95 207.63   4308.25   4559.35   4698.02   4838.38   5123.15  4963    1
x_rand[1]       316.81    1.63 144.61     99.38    247.09    305.30    366.85    597.63  7836    1
x_rand[2]       312.58    1.38 123.98    111.40    252.31    305.23    357.38    569.45  8117    1
attempt           0.03    0.00   0.18      0.00      0.00      0.00      0.00      1.00  7784    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -26967.65    0.03   1.74 -26971.89 -26968.58 -26967.31 -26966.37 -26965.23  3624    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:38:33 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_etd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           272.77    0.02   1.40    270.02    271.83    272.77    273.69    275.55  4475    1
mu[2]           267.14    0.02   1.28    264.64    266.26    267.12    268.00    269.68  4593    1
sigma[1]         60.01    0.02   1.28     57.55     59.15     60.00     60.86     62.53  3656    1
sigma[2]         54.94    0.02   1.12     52.79     54.18     54.92     55.70     57.19  3673    1
nu                5.27    0.01   0.38      4.58      5.01      5.25      5.51      6.05  4498    1
rho               0.81    0.00   0.01      0.79      0.80      0.81      0.81      0.82  4869    1
cov[1,1]       3603.09    2.54 153.48   3311.44   3498.40   3599.66   3703.53   3909.89  3659    1
cov[1,2]       2670.69    2.11 121.75   2440.79   2585.48   2667.90   2750.53   2920.02  3333    1
cov[2,1]       2670.69    2.11 121.75   2440.79   2585.48   2667.90   2750.53   2920.02  3333    1
cov[2,2]       3019.99    2.04 123.51   2787.14   2935.61   3016.10   3102.72   3271.26  3671    1
x_rand[1]       273.92    0.82  73.68    128.22    230.21    274.02    316.06    420.89  8061    1
x_rand[2]       269.13    0.75  67.33    133.79    228.98    268.90    307.33    404.88  8079    1
attempt           0.00    0.00   0.06      0.00      0.00      0.00      0.00      0.00  7660    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -24232.17    0.03   1.77 -24236.45 -24233.10 -24231.82 -24230.89 -24229.77  3293    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:41:09 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_ereg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.15    0.00 0.00    0.14    0.14    0.15    0.15    0.15  3942    1
mu[2]           0.14    0.00 0.00    0.14    0.14    0.14    0.15    0.15  3878    1
sigma[1]        0.09    0.00 0.00    0.08    0.09    0.09    0.09    0.09  3623    1
sigma[2]        0.09    0.00 0.00    0.08    0.08    0.09    0.09    0.09  3466    1
nu              3.39    0.00 0.21    3.02    3.25    3.38    3.53    3.82  4641    1
rho             0.66    0.00 0.02    0.63    0.65    0.66    0.67    0.69  5517    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3627    1
cov[1,2]        0.01    0.00 0.00    0.00    0.00    0.01    0.01    0.01  3292    1
cov[2,1]        0.01    0.00 0.00    0.00    0.00    0.01    0.01    0.01  3292    1
cov[2,2]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3471    1
x_rand[1]       0.18    0.00 0.11    0.02    0.11    0.16    0.23    0.43  7911    1
x_rand[2]       0.17    0.00 0.10    0.02    0.11    0.16    0.22    0.41  7898    1
attempt         0.16    0.00 0.43    0.00    0.00    0.00    0.00    1.00  8067    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         6053.37    0.03 1.73 6049.27 6052.43 6053.71 6054.65 6055.79  3589    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 22:53:58 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Skip Prob.--------------------------------------------')
[1] "---------------------------- Skip Prob.--------------------------------------------"
print(fit_eskip)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean    sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.42    0.00  0.00    0.41    0.42    0.42    0.42    0.43  4394    1
mu[2]           0.47    0.00  0.00    0.46    0.46    0.47    0.47    0.47  4472    1
sigma[1]        0.25    0.00  0.00    0.24    0.24    0.25    0.25    0.25  4291    1
sigma[2]        0.22    0.00  0.00    0.21    0.22    0.22    0.22    0.22  4205    1
nu            110.17    0.30 24.51   69.67   92.41  107.29  125.40  165.37  6568    1
rho             0.91    0.00  0.00    0.90    0.91    0.91    0.91    0.91  4932    1
cov[1,1]        0.06    0.00  0.00    0.06    0.06    0.06    0.06    0.06  4304    1
cov[1,2]        0.05    0.00  0.00    0.05    0.05    0.05    0.05    0.05  3900    1
cov[2,1]        0.05    0.00  0.00    0.05    0.05    0.05    0.05    0.05  3900    1
cov[2,2]        0.05    0.00  0.00    0.04    0.05    0.05    0.05    0.05  4205    1
x_rand[1]       0.45    0.00  0.22    0.06    0.29    0.44    0.61    0.90  7138    1
x_rand[2]       0.49    0.00  0.20    0.12    0.34    0.48    0.63    0.90  7290    1
attempt         0.05    0.00  0.22    0.00    0.00    0.00    0.00    1.00  7109    1
max_attempts   10.00     NaN  0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         5351.87    0.03  1.69 5347.60 5350.96 5352.16 5353.13 5354.21  3356    1

Samples were drawn using NUTS(diag_e) at Sun Feb 25 01:56:18 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# stan_trace(fit_egd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_egd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_egd, pars=c("rho", "mu", "sigma", "nu"))

# Gaze Duration
stan_trace(fit_egd)
stan_dens(fit_egd, separate_chains = TRUE)
stan_plot(fit_egd)

# Go Past Time
stan_trace(fit_egpt)
stan_dens(fit_egpt, separate_chains = TRUE)
stan_plot(fit_egpt)

# Total Duration
stan_trace(fit_etd)
stan_dens(fit_etd, separate_chains = TRUE)
stan_plot(fit_etd)

# FPReg
stan_trace(fit_ereg)
stan_dens(fit_ereg, separate_chains = TRUE)
stan_plot(fit_ereg)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_egd = as.numeric(extract(fit_egd, "rho")[[1]])
mean = mean(rho_egd)
crI = quantile(rho_egd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.7479
HPD: [0.7278, 0.7669]
crI: [0.7278, 0.767]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_egpt = as.numeric(extract(fit_egpt, "rho")[[1]])
mean = mean(rho_egpt)
crI = quantile(rho_egpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6334
HPD: [0.6052, 0.6617]
crI: [0.6044, 0.6612]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_etd = as.numeric(extract(fit_etd, "rho")[[1]])
mean = mean(rho_etd)
crI = quantile(rho_etd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_etd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.8095
HPD: [0.7939, 0.825]
crI: [0.7937, 0.8248]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
rho_ereg = as.numeric(extract(fit_ereg, "rho")[[1]])
mean = mean(rho_ereg)
crI = quantile(rho_ereg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6638
HPD: [0.6339, 0.6922]
crI: [0.6337, 0.6921]
print('---------------------------- Skip --------------------------------------------')
[1] "---------------------------- Skip --------------------------------------------"
rho_eskip = as.numeric(extract(fit_eskip, "rho")[[1]])
mean = mean(rho_eskip)
crI = quantile(rho_eskip, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_eskip), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.9081
HPD: [0.9012, 0.9148]
crI: [0.9011, 0.9148]
print('---------------------------- Gaze Duration--------------------------------------------')
egd_rand <- extract(fit_egd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(egd_rand[,1], egd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(egd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Go Past Time--------------------------------------------')
egpt_rand <- extract(fit_egpt, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(egpt_rand[,1], egpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egpt_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(egpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Total Duration--------------------------------------------')
etd_rand <- extract(fit_etd, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Total Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(etd_rand[,1], etd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(etd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(etd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(etd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression --------------------------------------------')
ereg_rand <- extract(fit_ereg, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "First Pass Regression") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(ereg_rand[,1], ereg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(ereg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ereg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

Bayesian – correlation between MoTR and word level statistics

print("Log Frequency")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$freq)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$freq)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(7, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

mfreq_temp <- stats_cor_df[c("motr_value", "freq")] %>%
  data.matrix()
efreq_temp <- stats_cor_df[c("eyetr_value", "freq")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mfreq_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Word Frequency")

# Plot the first data matrix gd_temp
plot(efreq_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Word Frequency")

motr & frequency

mfreq_data = list(x=mfreq_temp, N=nrow(mfreq_temp))

fit_mfreq = stan(
  file="stan_models/stats_correlation.stan", 
  data=mfreq_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_mfreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mfreq, file = paste0("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds"))

eyetr & frequency

efreq_data = list(x=efreq_temp, N=nrow(efreq_temp))

fit_efreq = stan(
  file="stan_models/stats_correlation.stan", 
  data=efreq_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_efreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_efreq, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds"))
print("Length")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$len)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$len)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(9, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

mlen_temp <- stats_cor_df[c("motr_value", "len")] %>%
  data.matrix()
elen_temp <- stats_cor_df[c("eyetr_value", "len")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mlen_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Word Length")

# Plot the first data matrix gd_temp
plot(elen_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Word Length")

motr & length

mlen_data = list(x=mlen_temp, N=nrow(mlen_temp))

fit_mlen = stan(
  file="stan_models/stats_correlation_len_normal.stan", 
  data=mlen_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_mlen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mlen, file = paste0("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds"))

eyetr & length

elen_data = list(x=elen_temp, N=nrow(elen_temp))

fit_elen = stan(
  file="stan_models/stats_correlation_len_normal.stan", 
  data=elen_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_elen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_elen, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds"))
print("Surprisal")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$surp)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$surp)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(8, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

msurp_temp <- stats_cor_df[c("motr_value", "surp")] %>%
  data.matrix()
esurp_temp <- stats_cor_df[c("eyetr_value", "surp")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(msurp_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Surprisal")

# Plot the first data matrix gd_temp
plot(esurp_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Surprisal")

motr & surprisal

msurp_data = list(x=msurp_temp, N=nrow(msurp_temp))

fit_msurp = stan(
  file="stan_models/stats_correlation.stan", 
  data=msurp_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_msurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_msurp, file = paste0("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds"))

eyetr & surprisal

esurp_data = list(x=esurp_temp, N=nrow(esurp_temp))

fit_esurp = stan(
  file="stan_models/stats_correlation.stan", 
  data=esurp_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_esurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_esurp, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds"))
fit_mfreq = readRDS("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds")
fit_efreq = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds")
fit_mlen = readRDS("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds")
fit_elen = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds")
fit_msurp = readRDS("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds")
fit_esurp = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds")

print('---------------------------- MoTR & Log Frequency --------------------------------------------')
print(fit_mfreq)
print('---------------------------- EyeTR & Log Frequency --------------------------------------------')
print(fit_efreq)
print('---------------------------- MoTR & Length --------------------------------------------')
print(fit_mlen)
print('---------------------------- EyeTR & Length --------------------------------------------')
print(fit_elen)
print('---------------------------- MoTR & Surprisal --------------------------------------------')
print(fit_msurp)
print('---------------------------- EyeTR & Surprisal --------------------------------------------')
print(fit_esurp)
# MoTR & Log Freq
stan_trace(fit_mfreq)
stan_dens(fit_mfreq, separate_chains = TRUE)
stan_plot(fit_mfreq)

# EyeTR & Log Freq
stan_trace(fit_efreq)
stan_dens(fit_efreq, separate_chains = TRUE)
stan_plot(fit_efreq)

# MoTR & Len
stan_trace(fit_mlen)
stan_dens(fit_mlen, separate_chains = TRUE)
stan_plot(fit_mlen)

# EyeTR & Len
stan_trace(fit_elen)
stan_dens(fit_elen, separate_chains = TRUE)
stan_plot(fit_elen)

# MoTR & Surprisal
stan_trace(fit_msurp)
stan_dens(fit_msurp, separate_chains = TRUE)
stan_plot(fit_msurp)

# EyeTR & Surprisal
stan_trace(fit_esurp)
stan_dens(fit_esurp, separate_chains = TRUE)
stan_plot(fit_esurp)
print('---------------------------- MoTR & Log Freq --------------------------------------------')
rho_mfreq = as.numeric(extract(fit_mfreq, "rho")[[1]])
mean = mean(rho_mfreq)
crI = quantile(rho_mfreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mfreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Log Freq --------------------------------------------')
rho_efreq = as.numeric(extract(fit_efreq, "rho")[[1]])
mean = mean(rho_efreq)
crI = quantile(rho_efreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_efreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- MoTR & Length --------------------------------------------')
rho_mlen = as.numeric(extract(fit_mlen, "rho")[[1]])
mean = mean(rho_mlen)
crI = quantile(rho_mlen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mlen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Length --------------------------------------------')
rho_elen = as.numeric(extract(fit_elen, "rho")[[1]])
mean = mean(rho_elen)
crI = quantile(rho_elen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_elen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- MoTR & Surprisal --------------------------------------------')
rho_msurp = as.numeric(extract(fit_msurp, "rho")[[1]])
mean = mean(rho_msurp)
crI = quantile(rho_msurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_msurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Surprisal --------------------------------------------')
rho_esurp = as.numeric(extract(fit_esurp, "rho")[[1]])
mean = mean(rho_esurp)
crI = quantile(rho_esurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_esurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
print('---------------------------- MoTR & Log Frequency--------------------------------------------')
mfreq_rand <- extract(fit_mfreq, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 12), type="n",
     xlab = "MoTR value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mfreq_rand[,1], mfreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mfreq_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mfreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mfreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Log Frequency--------------------------------------------')
efreq_rand <- extract(fit_efreq, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 500), ylim=c(0, 12), type="n",
     xlab = "Eye tracking value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(efreq_rand[,1], efreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(efreq_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(efreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(efreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- MoTR & Length --------------------------------------------')
mlen_rand <- extract(fit_mlen, "x_rand")[[1]]
# mlen_rand

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "MoTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlen_rand[,1], mlen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mlen_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Length --------------------------------------------')
elen_rand <- extract(fit_elen, "x_rand")[[1]]
# elen_rand

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "EyeTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(elen_rand[,1], elen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(elen_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(elen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- MoTR & Surprisal --------------------------------------------')
msurp_rand <- extract(fit_msurp, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "MoTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(msurp_rand [,1], msurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(msurp_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(msurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(msurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Surprisal --------------------------------------------')
esurp_rand <- extract(fit_esurp, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "EyeTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(esurp_rand [,1], esurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(esurp_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(esurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(esurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print("EyeTR vs. EyeTR Fisrt Pass Regression Prob. < 0.3 ")

ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5))

ereg_df_low = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5)) %>%
  filter(eyetr_value_1 < 0.3)
# View(ereg_df_low)

ereg_df_high = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5)) %>%
  filter(eyetr_value_1 >= 0.3)
# View(ereg_df_high) 

print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$p.value)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$estimate)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$p.value)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$estimate)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$p.value)

# View(egd_df)

ereg_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()
ereg_temp_low <- ereg_df_low[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()
ereg_temp_high <- ereg_df_high[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))
# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
     main = "FPReg all data Not Log-Transformed")
plot(ereg_temp_low, pch = 16, col = "blue",
     main = "FPReg < 0.3 Not Log-Transformed")
plot(ereg_temp_high, pch = 16, col = "blue",
     main = "FPReg > 0.3 Not Log-Transformed")
# -------fit model eyetr vs. eyetr FPReg <0.3 & >=0.3 ----------
reg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_all_data.rds"))

exploratory: divide eye tracking regression data into two parts.

# fit_ereg_all = readRDS("./eyetr_eyetr_FPReg_cor_all_data.rds")
fit_ereg_all = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor.rds")
fit_ereg_low = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_00-03.rds")
fit_ereg_high = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_03-1.rds")

print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
print(fit_ereg_all)
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
print(fit_ereg_low)
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
print(fit_ereg_high)
# # FPReg all data
stan_trace(fit_ereg_all)
stan_dens(fit_ereg_all, separate_chains = TRUE)
stan_plot(fit_ereg_all)

# # FPReg < 0.3
stan_trace(fit_ereg_low)
stan_dens(fit_ereg_low, separate_chains = TRUE)
stan_plot(fit_ereg_low)

# FPReg >= 0.3
stan_trace(fit_ereg_high)
stan_dens(fit_ereg_high, separate_chains = TRUE)
stan_plot(fit_ereg_high)
print('---------------------------- First Pass Regression all data--------------------------------------------')
rho_ereg_all = as.numeric(extract(fit_ereg_all, "rho")[[1]])
mean = mean(rho_ereg_all)
crI = quantile(rho_ereg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")


print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
rho_ereg_low = as.numeric(extract(fit_ereg_low, "rho")[[1]])
mean = mean(rho_ereg_low)
crI = quantile(rho_ereg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")


print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
rho_ereg_high = as.numeric(extract(fit_ereg_high, "rho")[[1]])
mean = mean(rho_ereg_high)
crI = quantile(rho_ereg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- First Pass Regression all data --------------------------------------------')
eallreg_rand <- extract(fit_ereg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(eallreg_rand[,1], eallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(eallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(eallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
elowreg_rand <- extract(fit_ereg_low, "x_rand")[[1]]
# print(elowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(elowreg_rand[,1], elowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_low, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(elowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
ehighreg_rand_samples <- extract(fit_ereg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(ehighreg_rand_samples), 900)
ehighreg_rand <- ehighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(ehighreg_rand[,1], ehighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_high, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(ehighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ehighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
LS0tCnRpdGxlOiAiQ29ycmVsYXRpb24gQW5hbHlzaXMgZm9yIE1vVFIgb24gUHJvdm8gRGF0YSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNoaGggPC0gc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzICMgSXQncyBhIGxpYnJhcnksIHNvIHNoaGghCgpzaGhoKGxpYnJhcnkoIG1nY3YgKSkKc2hoaChsaWJyYXJ5KGRwbHlyKSkKc2hoaChsaWJyYXJ5KGdncGxvdDIpKQpzaGhoKGxpYnJhcnkobG1lNCkpCnNoaGgobGlicmFyeSh0aWR5bXYpKQpzaGhoKGxpYnJhcnkoZ2FtbHNzKSkKc2hoaChsaWJyYXJ5KGdzdWJmbikpCnNoaGgobGlicmFyeShsbWVyVGVzdCkpCnNoaGgobGlicmFyeSh0aWR5dmVyc2UpKQpzaGhoKGxpYnJhcnkoYm9vdCkpCnNoaGgobGlicmFyeShyc2FtcGxlKSkKc2hoaChsaWJyYXJ5KHBsb3RyaXgpKQpzaGhoKGxpYnJhcnkoZ2dyZXBlbCkpCnNoaGgobGlicmFyeShtZ2N2KSkKCnNoaGgobGlicmFyeShicm1zKSkKc2hoaChsaWJyYXJ5KGJheWVzcGxvdCkpCnNoaGgobGlicmFyeShwYXRjaHdvcmspKQpzaGhoKGxpYnJhcnkoTUFTUykpCnNoaGgobGlicmFyeSh0aWR5cikpCnNoaGgobGlicmFyeShleHRyYURpc3RyKSkKc2hoaChsaWJyYXJ5KHB1cnJyKSkKIyBGb3IgZXhlcmNpc2VzIHdpdGggU3RhbiBjb2RlCnNoaGgobGlicmFyeShyc3RhbikpCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkKcnN0YW5fb3B0aW9ucyhhdXRvX3dyaXRlID0gRkFMU0UpCgpzaGhoKGxpYnJhcnkoY2FyKSkKc2hoaChsaWJyYXJ5KGNvZGEpKQpzaGhoKGxpYnJhcnkoZ3JpZEV4dHJhKSkKCnRoZW1lX3NldCh0aGVtZV9idygpKQpvcHRpb25zKGRpZ2l0cz00KQpvcHRpb25zKHNjaXBlbj05OTkpCnNldC5zZWVkKDQ0NCkKcGlwZV9tZXNzYWdlID0gZnVuY3Rpb24oLmRhdGEsIHN0YXR1cykge21lc3NhZ2Uoc3RhdHVzKTsgLmRhdGF9CgpgYGAKCgojIFJlYWQgaW4gTW9UUiBEYXRhCgpgYGB7cn0KCnJhdGUgPSAxNjAKCmZpbGVfcHJlZml4ID0gIi4uL2RhdGEvcHJvdm9fZjE2MC8iCmZuYW1lcyA9IGxpc3QuZmlsZXMocGF0aD1maWxlX3ByZWZpeCkKCmRmID0gZGF0YS5mcmFtZSgpCmZvciAoZiBpbiBmbmFtZXMpIHsKICB0ZW1wID0gcmVhZC5jc3YocGFzdGUwKGZpbGVfcHJlZml4LCAiLyIsIGYpKSAlPiUKICAgIG11dGF0ZShzdWJqID0gc3RyX3JlbW92ZShmLCAiX3JlYWRpbmdfbWVhc3VyZXMuY3N2IikpCiAgZGYgPSByYmluZChkZiwgdGVtcCkKfQoKIyBGaWx0ZXIgb3V0IHJlYWRlcnMgd2hvc2UgYWNjdXJhY3kgdG8gdGhlIGNvbXByZWhlbnNpb24gcXVlc3Rpb25zIHdlcmUgbGVzcyB0aGFuIDgwJS4KZmlsdGVyX2RmID0gZGYgJT4lCiAgZ3JvdXBfYnkocGFyYV9uciwgc3ViaikgJT4lIHN1bW1hcmlzZShjb3JyZWN0ID0gaWZfZWxzZSh1bmlxdWUoY29ycmVjdG5lc3MpID09IDEsIDEsIDApKSAlPiUgdW5ncm91cCgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBncm91cF9ieShzdWJqKSAlPiUgc3VtbWFyaXNlKHBfY29ycmVjdCA9IG1lYW4oY29ycmVjdCkpICU+JSB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHBfY29ycmVjdCA9IHJvdW5kKHBfY29ycmVjdCwgZGlnaXRzID0gMikpCgpmaWx0ZXJfZGYgPSBmaWx0ZXJfZGYgJT4lIGZpbHRlcihwX2NvcnJlY3QgPCAwLjgpCmZpbHRlcl9saXN0ID0gZmlsdGVyX2RmJHN1YmoKcGlsb3RfZXhjZXB0aW9ucyA8LSBjKCJyZWFkZXJfMjU1IiwgInJlYWRlcl8yNTYiLCAicmVhZGVyXzI1OSIsICJyZWFkZXJfMjYxIiwgInJlYWRlcl8yNjIiLCAicmVhZGVyXzI2MyIpCgpyYXdfZGYgPSBkZiAlPiUKICBmaWx0ZXIoISBzdWJqICVpbiUgYyhmaWx0ZXJfbGlzdCkgfCAoc3ViaiAlaW4lIHBpbG90X2V4Y2VwdGlvbnMpKSAlPiUKICBtdXRhdGUod29yZCA9IHN0cl90cmltKHdvcmQpKSAlPiUKICBtdXRhdGUoc3ViaiA9IHN0cl9yZW1vdmUoc3ViaiwgInJlYWRlcl8iKSkgJT4lCiAgbXV0YXRlKHN1YmogPSBhcy5jaGFyYWN0ZXIoc3ViaikpICU+JQogIG11dGF0ZShGUFJlZyA9IGlmX2Vsc2UodG90YWxfZHVyYXRpb24gPT0gMCwgLTEsIEZQUmVnKSkgJT4lICNJZiB0aGUgd29yZCBpcyBza2lwcGVkIHdlIGNhbid0IHNheSB0aGF0IGl0IHdhc24ndCByZWdyZXNzZWQgb24gdGhlIGZpcnN0IHBhc3MuIFNldCB0byBhICJOQSIKICBtdXRhdGUoc2tpcCA9IGlmX2Vsc2UoRlBGaXggPT0gMSwgMCwgMSkpICU+JSAjIHVzZSB0aGUgc2FtZSBkZWZpbmF0aW9uIGFzIGluIHByb3ZvIHBhcGVyCiAgZHBseXI6OnNlbGVjdChzdWJqLCBleHByX2lkLCBjb25kX2lkLCBwYXJhX25yLCB3b3JkLCB3b3JkX25yLCBmaXJzdF9kdXJhdGlvbiwgdG90YWxfZHVyYXRpb24sIGdhemVfZHVyYXRpb24sIGdvX3Bhc3RfdGltZSwgRlBSZWcsIHNraXApICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA3OjEwKSAlPiUKICBncm91cF9ieShwYXJhX25yLCBzdWJqLCBtZXRyaWMsIGNvbmRfaWQsIGV4cHJfaWQpICU+JQogIG11dGF0ZShmaXhlZCA9IGlmX2Vsc2UodmFsdWUgPiAwLCAxLCAwKSwKICAgICAgICAgbl9maXhlZCA9IHN1bShmaXhlZCksCiAgICAgICAgIG5fd29yZHMgPSBuKCkpICU+JQogICAgdW5ncm91cCgpICU+JQogIG11dGF0ZShmaXhfdGhyZXNob2xkID0gbl9maXhlZCA+IChuX3dvcmRzIC8gNSkpICU+JQogIG11dGF0ZShza2ltbWluZyA9IGlmX2Vsc2UoZml4X3RocmVzaG9sZCA9PSBGLFQsIEYpKSAlPiUKICBmaWx0ZXIoc2tpbW1pbmcgPT0gRikgJT4lCiAgc3ByZWFkKG1ldHJpYywgdmFsdWUpICU+JQogIGRwbHlyOjpzZWxlY3QoLWZpeGVkLCAtbl9maXhlZCwgLW5fd29yZHMsIC1maXhfdGhyZXNob2xkLCAtc2tpbW1pbmcpCmxlbmd0aCh1bmlxdWUocmF3X2RmJHN1YmopKQojIFZpZXcocmF3X2RmKQoKZGYgJT4lCiAgZmlsdGVyKCEgc3ViaiAlaW4lIGMoZmlsdGVyX2xpc3QpIHwgKHN1YmogJWluJSBwaWxvdF9leGNlcHRpb25zKSkgJT4lCiAgZmlsdGVyKEZQUmVnID49IDApICU+JQogIGRwbHlyOjpzZWxlY3QoRlBSZWcpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKEZQUmVnKSkKCmRmICU+JQogIGZpbHRlcighIHN1YmogJWluJSBjKGZpbHRlcl9saXN0KSB8IChzdWJqICVpbiUgcGlsb3RfZXhjZXB0aW9ucykpICU+JQogIGRwbHlyOjpzZWxlY3QoRlBGaXgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKEZQRml4KSkKCgpgYGAKCmBgYHtyfQpWaWV3KHJhd19kZikKYGBgCgoKYGBge3J9CiMgQXZlcmFnZSBhY3Jvc3Mgc3ViamVjdHMKbW90cl9hZ2dfZGYgPSByYXdfZGYgJT4lCiAgZ2F0aGVyKG1ldHJpYywgdmFsdWUsIDc6MTIpICU+JQogICAgZmlsdGVyKHZhbHVlID49IDApICU+JSAjUmVtb3ZlcyB0aGUgIk5BIiB2YWx1ZXMgZm9yIEZQUmVnCiAgCiAgICAjID09PT0gUmVtb3ZlIHNraXBwZWQgd29yZHMKICAgIG11dGF0ZSh6ZXJvID0gaWZfZWxzZSghbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWUgPT0gMCxULCBGKSkgJT4lCiAgICBmaWx0ZXIoemVybyA9PSBGKSAlPiUKICAKICAgIGRyb3BfbmEoKSAlPiUKICAgIGdyb3VwX2J5KHBhcmFfbnIsIHdvcmRfbnIsIHdvcmQsIG1ldHJpYykgJT4lCiAgICAKICAgICMgPT09IFJlbW92ZSBvdXRsaWVycyA+IDNTRAogICAgICAjIG11dGF0ZShvdXRsaWVyID0gaWZfZWxzZShtZXRyaWMgIT0gIkZQUmVnIiAmIHZhbHVlID4gKG1lYW4odmFsdWUpICsgMyAqIHNkKHZhbHVlKSksIFQsIEYpKSAlPiUgZmlsdGVyKG91dGxpZXIgPT0gRikgJT4lCiAgCiAgICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpLCBuc3ViaiA9IGxlbmd0aCh1bmlxdWUoc3ViaikpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShwYXJhX25yLCB3b3JkX25yKSAlPiUKICByZW5hbWUodGV4dF9pZCA9IHBhcmFfbnIsIHdvcmRfdGV4dF9pZHggPSB3b3JkX25yLCBtb3RyX3ZhbHVlID0gdmFsdWUpCiMgVmlldyhtb3RyX2FnZ19kZikKCmBgYAoKCgoKIyBDb21wYXJpc29uIHRvIFByb3ZvCgoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBzdXJwcmlzYWwsIGZyZXF1ZW5jeSBhbmQgbGVuZ3RoIGRhdGEKcHJvdm9fbW9kZWxpbmdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19zdGF0cy5jc3YiKSAlPiUKICBkcGx5cjo6c2VsZWN0KHRleHRfaWQsIHNlbnRfaWQsIHRyaWdnZXJfaWR4LCB3b3JkLCBmcmVxLCBzdXJwLCBsZW4pICU+JQogIHJlbmFtZSh3b3JkX2lkeCA9IHRyaWdnZXJfaWR4KQoKcHJvdm9fbW9kZWxpbmdfZGYKCmBgYAoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBleWV0cmFja2luZyBkYXRhCgpwcm92b19yYXdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19leWV0cmFja2luZy5jc3YiKQoKYGBgCgpgYGB7cn0KCiMgdW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkKIyBsZW5ndGgodW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkpCgpwcm92b19leWV0cmFja2luZ19kZiA9IHByb3ZvX3Jhd19kZiAlPiUKICBkcGx5cjo6c2VsZWN0KFBhcnRpY2lwYW50X0lELCBUZXh0X0lELCBTZW50ZW5jZV9OdW1iZXIsIFdvcmRfSW5fU2VudGVuY2VfTnVtYmVyLCBXb3JkLCBXb3JkX051bWJlciwgSUFfRklSU1RfRklYX1BST0dSRVNTSVZFLCBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwgSUFfRFdFTExfVElNRSwgSUFfUkVHUkVTU0lPTl9QQVRIX0RVUkFUSU9OLCBJQV9SRUdSRVNTSU9OX09VVCwgSUFfU0tJUCkgJT4lCiAgcmVuYW1lKCAjZmlyc3RfZHVyYXRpb24gPSBJQV9GSVJTVF9GSVhBVElPTl9EVVJBVElPTiwgICAKICAgICAgICAgIGdhemVfZHVyYXRpb24gPSBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwKICAgICAgICAgIHRvdGFsX2R1cmF0aW9uID0gSUFfRFdFTExfVElNRSwKICAgICAgICAgIGdvX3Bhc3RfdGltZSA9IElBX1JFR1JFU1NJT05fUEFUSF9EVVJBVElPTiwKICAgICAgICAgIHN1YmogPSBQYXJ0aWNpcGFudF9JRCwKICAgICAgICAgIHRleHRfaWQgPSBUZXh0X0lELAogICAgICAgICAgc2VudF9pZCA9IFNlbnRlbmNlX051bWJlciwKICAgICAgICAgIHdvcmRfaWR4ID0gV29yZF9Jbl9TZW50ZW5jZV9OdW1iZXIsCiAgICAgICAgICB3b3JkX3RleHRfaWR4ID0gV29yZF9OdW1iZXIsICAgIyBJQV9JRD8KICAgICAgICAgIHdvcmQgPSBXb3JkLCAgICAgICMgV29yZD8KICAgICAgICAgIEZQUmVnID0gSUFfUkVHUkVTU0lPTl9PVVQsCiAgICAgICAgICBza2lwID0gSUFfU0tJUCwKICAgICAgICAgIGZmX3Byb2dyZXNzaXZlID0gSUFfRklSU1RfRklYX1BST0dSRVNTSVZFKSAlPiUKICBtdXRhdGUoZmlyc3RfZHVyYXRpb24gPSBnYXplX2R1cmF0aW9uKSAlPiUKICBtdXRhdGUoZ2F6ZV9kdXJhdGlvbiA9IGlmX2Vsc2UoZmZfcHJvZ3Jlc3NpdmUgPT0gMCwgMCwgYXMuZG91YmxlKGdhemVfZHVyYXRpb24pKSwKICAgICAgICAgZ29fcGFzdF90aW1lID0gaWZfZWxzZShmZl9wcm9ncmVzc2l2ZSA9PSAwLCAwLCBhcy5kb3VibGUoZ29fcGFzdF90aW1lKSkpICU+JQogIGRwbHlyOjpzZWxlY3QoLWZmX3Byb2dyZXNzaXZlKSAlPiUKICAKICBtdXRhdGUoCiAgICBnYXplX2R1cmF0aW9uID0gaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZ2F6ZV9kdXJhdGlvbikpLAogICAgICBnb19wYXN0X3RpbWUgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIDAsIGFzLmRvdWJsZShnb19wYXN0X3RpbWUpKSwKICAgICAgRlBSZWcgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIC0xLCBhcy5kb3VibGUoRlBSZWcpKSwKICAgICAgZmlyc3RfZHVyYXRpb24gPSAgaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZmlyc3RfZHVyYXRpb24pKSwKICApICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA3OjEyKSAlPiUKICBmaWx0ZXIodmFsdWUgPj0gMCkgJT4lICAgICAgICAgICMgZmlsdGVyIHNraXBwZWQgd29yZCBpbiBleWUgdHJhY2tpbmcgZGF0YSBmb3IgRlBSZWcKICAKICAjID09PT0gUmVtb3ZlIHNraXBwZWQgd29yZHMKICBtdXRhdGUoemVybyA9IGlmX2Vsc2UoIW1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIHZhbHVlID09IDAsVCwgRikpICU+JQogIGZpbHRlcih6ZXJvID09IEYpICU+JQogIAogICMgbXV0YXRlKHZhbHVlID0gaWZfZWxzZShpcy5uYSh2YWx1ZSksIGFzLmludGVnZXIoMCksIGFzLmludGVnZXIodmFsdWUpKSkgJT4lCiAgIyBtdXRhdGUodmFsdWUgPSBpZl9lbHNlKG1ldHJpYyAhPSAiRlBSZWciICYgaXMubmEodmFsdWUpLCBhcy5pbnRlZ2VyKDApLCBhcy5pbnRlZ2VyKHZhbHVlKSkpICU+JQogIGRyb3BfbmEoKSAlPiUKICBtdXRhdGUod29yZCA9IHN0cl90cmltKHdvcmQpKSAlPiUKICBtdXRhdGUoc3ViaiA9IHN0cl9yZW1vdmUoc3ViaiwgIlN1YiIpKSAlPiUKICBtdXRhdGUoc3ViaiA9IGFzLmludGVnZXIoc3ViaikpICU+JQogICAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgCiAgIyA9PT0gUmVtb3ZlIG91dGxpZXJzID4gM1NECiAgICAjIG11dGF0ZShvdXRsaWVyID0gaWZfZWxzZSghIG1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIHZhbHVlID4gKG1lYW4odmFsdWUpICsgMyAqIHNkKHZhbHVlKSApLCBULCBGKSkgJT4lCiAgICAjIGZpbHRlcihvdXRsaWVyID09IEYpICU+JQogIAogIHVuZ3JvdXAoKSAjJT4lCgojIEFnZ3JlZ2F0ZSBjcm9zcy1wYXJ0aWNpcGFudCBkYXRhIGZvciBhbGwgc3ViamVjdHMKcHJvdm9fZXlldHJhY2tpbmdfYWdnX2RmID0gcHJvdm9fZXlldHJhY2tpbmdfZGYgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSwKICAgICAgICAgICAgICBuc3ViaiA9IGxlbmd0aCh1bmlxdWUoc3ViaikpKSAlPiUKICAgIHVuZ3JvdXAoKQoKcHJvdm9fcmF3X2RmICU+JQogIGRwbHlyOjpzZWxlY3QoSUFfUkVHUkVTU0lPTl9PVVQpICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKElBX1JFR1JFU1NJT05fT1VUKSkKCnByb3ZvX3Jhd19kZiAlPiUKICBkcGx5cjo6c2VsZWN0KElBX1NLSVApICU+JQogIGRyb3BfbmEoKSAlPiUKICBzdW1tYXJpc2UoIG0gPSBtZWFuKElBX1NLSVApKQoKYGBgCgpgYGB7cn0KCiMgU3BsaXQgdGhlIGV5ZXRyYWNraW5nIGRhdGEgaW4gdHdvIGJ5IHN1YmplY3RzIHRvIHNlZSBob3cgd2VsbCBpdCBjb3JyZWxhdGVzIHdpdGggaXRzZWxmCnByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmX3RlbXAgPSBwcm92b19leWV0cmFja2luZ19kZiAlPiUKICBmaWx0ZXIoc3ViaiA8PSA0MikgJT4lCiAgbXV0YXRlKHdvcmRfdGV4dF9pZHggPSBhcy5pbnRlZ2VyKHdvcmRfdGV4dF9pZHggLSAxKSkgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHJlbmFtZSh2YWx1ZV8xID0gdmFsdWUpICMlPiUKICAjIGRwbHlyOjpzZWxlY3QoLXNlbnRfaWQsIC13b3JkX2lkeCkKCgpwcm92b19leWV0cmFja2luZ19zdWJqMV9kZiA9IG1lcmdlKHByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmX3RlbXAsIG1vdHJfYWdnX2RmLCBieT1jKCJ0ZXh0X2lkIiwgIndvcmRfdGV4dF9pZHgiLCAibWV0cmljIikpICU+JQogIGFycmFuZ2UodGV4dF9pZCwgc2VudF9pZCwgd29yZF9pZHgpICU+JQogIGZpbHRlcighKHRleHRfaWQgPT0gMTMgJiB3b3JkX3RleHRfaWR4ID49IDIwICYgd29yZF90ZXh0X2lkeCA8PSA1MikpICU+JQogIGZpbHRlcighKHRleHRfaWQgPT0gMyAmIHdvcmRfdGV4dF9pZHggPj0gNDYgJiB3b3JkX3RleHRfaWR4IDw9IDU3KSkgJT4lCiAgcmVuYW1lKHdvcmQgPSB3b3JkLnkpICU+JQogIGRwbHlyOjpzZWxlY3QodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgbWV0cmljLCB3b3JkLCB2YWx1ZV8xKSAKCiMgVmlldyhwcm92b19leWV0cmFja2luZ19zdWJqMV9kZikKCnByb3ZvX2V5ZXRyYWNraW5nX3N1YmoyX2RmID0gcHJvdm9fZXlldHJhY2tpbmdfZGYgJT4lCiAgZmlsdGVyKHN1YmogPiA0MikgJT4lCiAgbXV0YXRlKHdvcmRfdGV4dF9pZHggPSBhcy5pbnRlZ2VyKHdvcmRfdGV4dF9pZHggLSAxKSkgJT4lCiAgZ3JvdXBfYnkodGV4dF9pZCwgd29yZF90ZXh0X2lkeCwgc2VudF9pZCwgd29yZF9pZHgsIHdvcmQsIG1ldHJpYykgJT4lCiAgICBzdW1tYXJpc2UodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgdW5ncm91cCgpICU+JQogICAgcmVuYW1lKHZhbHVlXzIgPSB2YWx1ZSklPiUKICBkcGx5cjo6c2VsZWN0KC1zZW50X2lkLCAtd29yZF9pZHgpCgojIFZpZXcocHJvdm9fZXlldHJhY2tpbmdfc3ViajJfZGYpCiAgCnByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgPSBtZXJnZShwcm92b19leWV0cmFja2luZ19zdWJqMl9kZiwgcHJvdm9fZXlldHJhY2tpbmdfc3ViajFfZGYsIGJ5PWMoInRleHRfaWQiLCAid29yZF90ZXh0X2lkeCIsICJtZXRyaWMiKSkgJT4lCiAgIyBmaWx0ZXIod29yZC54ID09IHdvcmQueSkgJT4lCiAgZHBseXI6OnNlbGVjdCgtd29yZC55KSAlPiUKICAjID09PSBSZW1vdmUgb3V0bGllcnMgPiAzU0QKICAjIGdyb3VwX2J5KG1ldHJpYykgJT4lCiAgIyAgIG11dGF0ZShtb3RyX291dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWVfMSA+IChtZWFuKHZhbHVlXzEpICsgMyAqIHNkKHZhbHVlXzEpICksIFQsIEYpKSAlPiUKICAjICAgZmlsdGVyKG1vdHJfb3V0bGllciA9PSBGKSAlPiUKICAjICAgbXV0YXRlKGV5ZXRyX291dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWVfMiA+IChtZWFuKHZhbHVlXzIpICsgMyAqIHNkKHZhbHVlXzIpICksIFQsIEYpKSAlPiUKICAjICAgZmlsdGVyKGV5ZXRyX291dGxpZXIgPT0gRikgJT4lCiAgIyB1bmdyb3VwKCkgJT4lCiAgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCBjKCJ2YWx1ZV8xIiwgInZhbHVlXzIiKSkgIyU+JQogICMgZHBseXI6OnNlbGVjdCgtbW90cl9vdXRsaWVyLCAtZXlldHJfb3V0bGllcikKCiMgVmlldyhwcm92b19leWV0cl9ncm91cGVkX2RmKQoKYGBgCgoKYGBge3J9CnByb3ZvX2RmID0gbWVyZ2UocHJvdm9fZXlldHJhY2tpbmdfYWdnX2RmLCBwcm92b19tb2RlbGluZ19kZiwgYnk9YygidGV4dF9pZCIsICJzZW50X2lkIiwgIndvcmRfaWR4IikpICU+JQogIG11dGF0ZSh3b3JkX3RleHRfaWR4ID0gYXMuaW50ZWdlcih3b3JkX3RleHRfaWR4IC0gMSkpICU+JQogIGFycmFuZ2UodGV4dF9pZCwgc2VudF9pZCwgd29yZF9pZHgpICU+JQogIHJlbmFtZShleWV0cl92YWx1ZSA9IHZhbHVlKSAKCnByb3ZvX2RmID0gbWVyZ2UocHJvdm9fZGYsIG1vdHJfYWdnX2RmLCBieT1jKCJ0ZXh0X2lkIiwgIndvcmRfdGV4dF9pZHgiLCAibWV0cmljIikpICU+JQphcnJhbmdlKHRleHRfaWQsIHNlbnRfaWQsIHdvcmRfaWR4KSAlPiUKICAjIGFsbW9zdCBhbGwgdGhlIHdvcmQueCAhPSB3b3JkLnkgaXMgYmVjYXVzZSBvZiBub3JtYWxpemF0aW9uIHByb2JsZW0sIHNvIHdlIGNhbiBrZWVwIHRoZW0sIGluc3RlYWQsIGRlbGV0aW5nIHNvbWUgc3BlY2lhbCBjYXNlcwpmaWx0ZXIoISh0ZXh0X2lkID09IDEzICYgd29yZF90ZXh0X2lkeCA+PSAyMCAmIHdvcmRfdGV4dF9pZHggPD0gNTIpKSAlPiUKICBmaWx0ZXIoISh0ZXh0X2lkID09IDMgJiB3b3JkX3RleHRfaWR4ID49IDQ2ICYgd29yZF90ZXh0X2lkeCA8PSA1NykpICU+JQojIGZpbHRlcih3b3JkLnggPT0gd29yZCkgIyU+JQpkcGx5cjo6c2VsZWN0KC13b3JkLngsIC13b3JkLnkpICU+JQogIAojID09PSBSZW1vdmUgb3V0bGllcnMgPiAzU0QKIyBncm91cF9ieShtZXRyaWMpICU+JQojICAgbXV0YXRlKG1vdHJfb3V0bGllciA9IGlmX2Vsc2UoISBtZXRyaWMgJWluJSBjKCJGUFJlZyIsICJza2lwIikgJiBtb3RyX3ZhbHVlID4gKG1lYW4obW90cl92YWx1ZSkgKyAzICogc2QobW90cl92YWx1ZSkgKSwgVCwgRikpICU+JQojICAgZmlsdGVyKG1vdHJfb3V0bGllciA9PSBGKSAlPiUKIyAgIG11dGF0ZShleWV0cl9vdXRsaWVyID0gaWZfZWxzZSghIG1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIGV5ZXRyX3ZhbHVlID4gKG1lYW4oZXlldHJfdmFsdWUpICsgMyAqIHNkKGV5ZXRyX3ZhbHVlKSApLCBULCBGKSkgJT4lCiMgICBmaWx0ZXIoZXlldHJfb3V0bGllciA9PSBGKSAlPiUKIyB1bmdyb3VwKCkgJT4lCiAgCmdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpKSAjJT4lCiMgZHBseXI6OnNlbGVjdCgtbW90cl9vdXRsaWVyLCAtZXlldHJfb3V0bGllcikKICAKIyBwcm92b19kZgpgYGAKCgojIEJheWVzaWFuIC0tIHVzZSBTdGFuIC0tIG1vdHIgJiBleWV0ciBjb3JyZWxhdGlvbgpgYGB7cn0KcHJpbnQoIkdhemUgRHVyYXRpb24iKQpnZF9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDEpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxKQogICkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlX2xvZyA9IGxvZyhleWV0cl92YWx1ZSksCiAgICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbG9nKG1vdHJfdmFsdWUpKQpwcmludChjb3IudGVzdChnZF9kZiRleWV0cl92YWx1ZSwgZ2RfZGYkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGdkX2RmJGV5ZXRyX3ZhbHVlX2xvZywgZ2RfZGYkbW90cl92YWx1ZV9sb2cpJGVzdGltYXRlKQojIFZpZXcoZ2RfZGYpCmBgYAoKCmBgYHtyfQpnZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCiAgCmBgYAoKCgpgYGB7cn0KIyBjZW50ZXIgZGF0YSBhcm91bmQgMC4KCmdkX3RlbXAgPC0gZ2RfZGZbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUKICAgIyBtdXRhdGUoZXlldHJfdmFsdWUgPSBleWV0cl92YWx1ZSAtIG1lYW4oZXlldHJfdmFsdWUpLAogICAjICAgICAgbW90cl92YWx1ZSA9IG1vdHJfdmFsdWUgLSBtZWFuKG1vdHJfdmFsdWUpKSAlPiUKICBkYXRhLm1hdHJpeCgpCgpnZF90ZW1wX2xvZyA8LSBnZF9kZltjKCJleWV0cl92YWx1ZV9sb2ciLCAibW90cl92YWx1ZV9sb2ciKV0gJT4lCiBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gZXlldHJfdmFsdWVfbG9nIC0gbWVhbihleWV0cl92YWx1ZV9sb2cpLCAKICAgICAgICBtb3RyX3ZhbHVlX2xvZyA9IG1vdHJfdmFsdWVfbG9nIC0gbWVhbihtb3RyX3ZhbHVlX2xvZykpICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChnZF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCiMgUGxvdCB0aGUgc2Vjb25kIGRhdGEgbWF0cml4IGdkX3RlbXBfbG9nCnBsb3QoZ2RfdGVtcF9sb2csIHBjaCA9IDE2LCBjb2wgPSAicmVkIiwKICAgICBtYWluID0gIkNlbnRlcmVkIExvZy1UcmFuc2Zvcm1lZCIpCgpgYGAKCgoKYGBge3IsIGV2YWw9RkFMU0V9CmdkX2RhdGEgPSBsaXN0KHg9Z2RfdGVtcCwgTj1ucm93KGdkX3RlbXApKQoKZml0X2dkID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9Z2RfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2dkQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9nZCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpKQoKYGBgCgpgYGB7cn0KcHJpbnQoIkdvIFBhc3QgVGltZSIpCmdwdF9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnb19wYXN0X3RpbWUiKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDEpCiAgKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gbG9nKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBsb2cobW90cl92YWx1ZSkpCnByaW50KGNvci50ZXN0KGdwdF9kZiRleWV0cl92YWx1ZSwgZ3B0X2RmJG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdChncHRfZGYkZXlldHJfdmFsdWVfbG9nLCBncHRfZGYkbW90cl92YWx1ZV9sb2cpJGVzdGltYXRlKQoKZ3B0X2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjE1KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmdwdF90ZW1wIDwtIGdwdF9kZltjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgpncHRfdGVtcF9sb2cgPC0gZ3B0X2RmW2MoImV5ZXRyX3ZhbHVlX2xvZyIsICJtb3RyX3ZhbHVlX2xvZyIpXSAlPiUKIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBleWV0cl92YWx1ZV9sb2cgLSBtZWFuKGV5ZXRyX3ZhbHVlX2xvZyksIAogICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbW90cl92YWx1ZV9sb2cgLSBtZWFuKG1vdHJfdmFsdWVfbG9nKSkgJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ3B0X3RlbXAKcGxvdChncHRfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQojIFBsb3QgdGhlIHNlY29uZCBkYXRhIG1hdHJpeCBncHRfdGVtcF9sb2cKcGxvdChncHRfdGVtcF9sb2csIHBjaCA9IDE2LCBjb2wgPSAicmVkIiwKICAgICBtYWluID0gIkNlbnRlcmVkIExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBnbyBwYXN0IHRpbWUgLS0tLS0tLS0tLQpncHRfZGF0YSA9IGxpc3QoeD1ncHRfdGVtcCwgTj1ucm93KGdwdF90ZW1wKSkKZml0X2dwdCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWdwdF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZ3B0QHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9ncHQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIlRvdGFsIER1cmF0aW9uIikKdGRfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAidG90YWxfZHVyYXRpb24iKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDEpCiAgKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gbG9nKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBsb2cobW90cl92YWx1ZSkpCnByaW50KGNvci50ZXN0KHRkX2RmJGV5ZXRyX3ZhbHVlLCB0ZF9kZiRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QodGRfZGYkZXlldHJfdmFsdWVfbG9nLCB0ZF9kZiRtb3RyX3ZhbHVlX2xvZykkZXN0aW1hdGUpCgp0ZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgp0ZF90ZW1wIDwtIHRkX2RmW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCnRkX3RlbXBfbG9nIDwtIHRkX2RmW2MoImV5ZXRyX3ZhbHVlX2xvZyIsICJtb3RyX3ZhbHVlX2xvZyIpXSAlPiUKIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBleWV0cl92YWx1ZV9sb2cgLSBtZWFuKGV5ZXRyX3ZhbHVlX2xvZyksIAogICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbW90cl92YWx1ZV9sb2cgLSBtZWFuKG1vdHJfdmFsdWVfbG9nKSkgJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggdGRfdGVtcApwbG90KHRkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKIyBQbG90IHRoZSBzZWNvbmQgZGF0YSBtYXRyaXggdGRfdGVtcF9sb2cKcGxvdCh0ZF90ZW1wX2xvZywgcGNoID0gMTYsIGNvbCA9ICJyZWQiLAogICAgIG1haW4gPSAiQ2VudGVyZWQgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIHRvdGFsIGR1cmF0aW9uIC0tLS0tLS0tLS0KdGRfZGF0YSA9IGxpc3QoeD10ZF90ZW1wLCBOPW5yb3codGRfdGVtcCkpCmZpdF90ZCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPXRkX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF90ZEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfdGQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikpCmBgYAoKYGBge3J9CnByaW50KCJGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4iKQpyZWdfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkKcHJpbnQoY29yLnRlc3QocmVnX2RmJGV5ZXRyX3ZhbHVlLCByZWdfZGYkbW90cl92YWx1ZSkkZXN0aW1hdGUpCgojIFZpZXcocmVnX2RmKQpyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTMpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXAgPC0gcmVnX2RmW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IHRkX3RlbXAKcGxvdChyZWdfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgLS0tLS0tLS0tLQpyZWdfZGF0YSA9IGxpc3QoeD1yZWdfdGVtcCwgTj1ucm93KHJlZ190ZW1wKSkKZml0X3JlZyA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX25vcm1hbF9yZWcuc3RhbiIsIAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2Ryb3Awcy5yZHMiKSkKYGBgCgoKIyByYW5rIHRyYW5zZm9ybWF0aW9uIGZvciBGUFJlZwpgYGB7ciwgZXZhbD1GQUxTRX0KcmVnX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgbXV0YXRlKAogICAgZXlldHJfdmFsdWVfcmFuayA9IGlmZWxzZShleWV0cl92YWx1ZSA+IDAsIHJhbmsoZXlldHJfdmFsdWUpLCBOQSksCiAgICBtb3RyX3ZhbHVlX3JhbmsgPSBpZmVsc2UobW90cl92YWx1ZSA+IDAsIHJhbmsobW90cl92YWx1ZSksIE5BKQogICkgJT4lCiAgZHJvcF9uYSgpCiMgICBtdXRhdGUoCiMgICBleWV0cl92YWx1ZV9yYW5rID0gcmFuayhleWV0cl92YWx1ZSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAojICAgbW90cl92YWx1ZV9yYW5rID0gcmFuayhtb3RyX3ZhbHVlLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKIyApCiMgVmlldyhyZWdfZGYpCgpwcmludChjb3IudGVzdChyZWdfZGYkZXlldHJfdmFsdWVfcmFuaywgcmVnX2RmJG1vdHJfdmFsdWVfcmFuaykkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZiRleWV0cl92YWx1ZV9yYW5rLCByZWdfZGYkbW90cl92YWx1ZV9yYW5rLCBtZXRob2QgPSAia2VuZGFsbCIpKQoKCnJlZ19kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxNDoxNSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpyZWdfdGVtcCA8LSByZWdfZGZbYygiZXlldHJfdmFsdWVfcmFuayIsICJtb3RyX3ZhbHVlX3JhbmsiKV0gJT4lIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IHRkX3RlbXAKcGxvdChyZWdfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIlJhbmsgVHJhbnNmb3JtZWQiKQogIApgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgUkFOSy0tLS0tLS0tLS0KcmVnX2RhdGEgPSBsaXN0KHg9cmVnX3RlbXAsIE49bnJvdyhyZWdfdGVtcCkpCmZpdF9yZWcgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbl9yYW5rLnN0YW4iLCAKICBkYXRhPXJlZ19kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz00LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfcmVnQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9yZWcsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl9yYW5rX2Ryb3Awcy5yZHMiKSkKYGBgCgpgYGB7cn0KcHJpbnQoInNraXAgUHJvYi4iKQpza2lwX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gInNraXAiKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIGZpbHRlcihleWV0cl92YWx1ZSA+IDAsIG1vdHJfdmFsdWUgPiAwKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMWUtNSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDFlLTUpKQpwcmludChjb3IudGVzdChza2lwX2RmJGV5ZXRyX3ZhbHVlLCBza2lwX2RmJG1vdHJfdmFsdWUpJGVzdGltYXRlKQoKIyBWaWV3KHJlZ19kZikKc2tpcF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxMykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpza2lwX3RlbXAgPC0gc2tpcF9kZltjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3Qoc2tpcF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBza2lwIC0tLS0tLS0tLS0Kc2tpcF9kYXRhID0gbGlzdCh4PXNraXBfdGVtcCwgTj1ucm93KHNraXBfdGVtcCkpCmZpdF9za2lwID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfbm9ybWFsX3JlZy5zdGFuIiwgCiAgZGF0YT1za2lwX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9za2lwQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9za2lwLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikpCmBgYAoKYGBge3J9CmZpdF9nZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dhemVfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfZ3B0ID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ29fcGFzdF90aW1lX2Nvcl9kcm9wMHMucmRzIikKZml0X3RkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfcmVnID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2Ryb3Awcy5yZHMiKQpmaXRfcmVnX3JhbmsgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfcmFua19kcm9wMHMucmRzIikKZml0X3NraXAgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikKCiMgbW9kZWxzIGZvciBkcm9wIDBzCiMgZml0X2dkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpCiMgZml0X2dwdCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpCiMgZml0X3RkID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQojIGZpdF9yZWcgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vcmFua2VkX21vdHJfZXlldHJfRlBSZWdfY29yLnJkcyIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHYXplIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfZ2QpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2dwdCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF90ZCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfcmVnKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gUkFOSy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X3JlZ19yYW5rKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBTa2lwIFByb2IuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfc2tpcCkKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnM9YygicmhvIiwgIm11IiwgInNpZ21hIiwgIm51IikpCiMgc3Rhbl9kZW5zKGZpdF9nZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X2dkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQoKIyBHYXplIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2dkKQpzdGFuX2RlbnMoZml0X2dkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2dkKQoKIyBHbyBQYXN0IFRpbWUKc3Rhbl90cmFjZShmaXRfZ3B0KQpzdGFuX2RlbnMoZml0X2dwdCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9ncHQpCgojIFRvdGFsIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X3RkKQpzdGFuX2RlbnMoZml0X3RkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3RkKQoKIyBGUFJlZwpzdGFuX3RyYWNlKGZpdF9yZWcpCnN0YW5fZGVucyhmaXRfcmVnLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3JlZykKCmBgYAoKYGBge3IsIGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTEwLCBldmFsPUZBTFNFfQpwMSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdyaG8nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAyIDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAncmhvJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDMgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnA0IDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpwNSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIGluY193YXJtdXAgPSBGQUxTRSkKcDYgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnA3IDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgaW5jX3dhcm11cCA9IEZBTFNFKQpwOCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDkgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnc2lnbWFbMl0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAxMCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzJdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDExIDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ251JywgaW5jX3dhcm11cCA9IEZBTFNFKQpwMTIgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdudScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCgoKIyBVc2UgZ3JpZC5hcnJhbmdlKCkgdG8gYXJyYW5nZSB0aGUgcGxvdHMKIyBncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDcsIHA4LCBwOSwgcDEwLCBwMTEsIHAxMiwgbmNvbD0yLCBucm93PTYpCgpgYGAKCgoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19nZCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ2QsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZ2QpCmNySSA9IHF1YW50aWxlKHJob19nZCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19nZCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2dwdCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ3B0LCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2dwdCkKY3JJID0gcXVhbnRpbGUocmhvX2dwdCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19ncHQpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX3RkID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF90ZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob190ZCkKY3JJID0gcXVhbnRpbGUocmhvX3RkLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3RkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKIyByaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG9bMSwgMl0iKVtbMV1dKQpyaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fcmVnKQpjckkgPSBxdWFudGlsZShyaG9fcmVnLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3JlZyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBSQU5LLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQojIHJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZywgInJob1sxLCAyXSIpW1sxXV0pCnJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZ19yYW5rLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX3JlZykKY3JJID0gcXVhbnRpbGUocmhvX3JlZywgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19yZWcpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU2tpcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCiMgcmhvX3JlZyA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfcmVnLCAicmhvWzEsIDJdIilbWzFdXSkKcmhvX3NraXAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3NraXAsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fc2tpcCkKY3JJID0gcXVhbnRpbGUocmhvX3NraXAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fc2tpcCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmdkX3JhbmQgPC0gZXh0cmFjdChmaXRfZ2QsICJ4X3JhbmQiKVtbMV1dCiMgeF9yYW5kX2ZpbHRlcmVkIDwtIHhfcmFuZFthcHBseSh4X3JhbmQsIDEsIGZ1bmN0aW9uKHgpIGFsbCh4ID4gMCkpLF0KIyB4X3JhbmRfZmlsdGVyZWQKCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA0MDApLCB5bGltPWMoMCwgNzAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZ2RfcmFuZFssMV0sIGdkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhnZF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGdkX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmdwdF9yYW5kIDwtIGV4dHJhY3QoZml0X2dwdCwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA4MDApLCB5bGltPWMoMCwgMTIwMCksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJHbyBQYXN0IFRpbWUiKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZ3B0X3JhbmRbLDFdLCBncHRfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGdwdF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFRvdGFsIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQp0ZF9yYW5kIDwtIGV4dHJhY3QoZml0X3RkLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIlRvdGFsIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKHRkX3JhbmRbLDFdLCB0ZF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHModGRfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZSh0ZF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKHRkX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfcmVnLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhyZWdfcmFuZFssMV0sIHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UocmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UocmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gU2tpcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnNraXBfcmFuZCA8LSBleHRyYWN0KGZpdF9za2lwLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJTa2lwIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKHNraXBfcmFuZFssMV0sIHNraXBfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHNraXBfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShza2lwX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2Uoc2tpcF9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCmBgYAoKIyBtb2RlbCBtb3RyIGV5ZXRyIEZQUmVnIGNvcnJlbGF0aW9uIChleWV0ciA8IDAuMykKYGBge3J9CnByaW50KCJGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gYWxsIGFuZCAgPCAwLjMiKQpyZWdfZGZfYWxsID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkKCnJlZ19kZl9sb3dfZHJvcDAgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlIDwgMC4zKQoKcmVnX2RmX2xvdyA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA8IDAuMykKICAjIG11dGF0ZShleWV0cl92YWx1ZSA9IGV4cChleWV0cl92YWx1ZSksCiAgICAgICAgICMgbW90cl92YWx1ZSA9IGV4cChtb3RyX3ZhbHVlKQogICAgICAgICAjICkKIyBWaWV3KHJlZ19kZikKCnByaW50KGNvci50ZXN0KHJlZ19kZl9hbGwkZXlldHJfdmFsdWUsIHJlZ19kZl9hbGwkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9hbGwkZXlldHJfdmFsdWUsIHJlZ19kZl9hbGwkbW90cl92YWx1ZSkkcC52YWx1ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2xvdyRleWV0cl92YWx1ZSwgcmVnX2RmX2xvdyRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2xvdyRleWV0cl92YWx1ZSwgcmVnX2RmX2xvdyRtb3RyX3ZhbHVlKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93X2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93X2Ryb3AwJG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93X2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93X2Ryb3AwJG1vdHJfdmFsdWUpJHAudmFsdWUpCgojIFZpZXcocmVnX2RmKQpyZWdfZGZfbG93ICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjEzKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCnJlZ190ZW1wX2FsbCA8LSByZWdfZGZfYWxsW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKcmVnX3RlbXBfbG93IDwtIHJlZ19kZl9sb3dbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQpyZWdfdGVtcF9sb3dfZHJvcDAgPC0gcmVnX2RmX2xvd19kcm9wMFtjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3QocmVnX3RlbXBfbG93LCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyA8IDAuMyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PXJlZ190ZW1wX2FsbCwgTj1ucm93KHJlZ190ZW1wX2FsbCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX2FsbF9kYXRhX2Ryb3Awcy5yZHMiKSkKYGBgCgoKIyBtb2RlbCBtb3RyIGV5ZXRyIEZQUmVnIGNvcnJlbGF0aW9uIChleWV0ciA+PSAwLjMpCmBgYHtyfQpwcmludCgiRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuID49IDAuMyIpCnJlZ19kZl9oaWdoX2Ryb3AwID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+PSAwLjMpCgpyZWdfZGZfaGlnaCA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgZmlsdGVyKGV5ZXRyX3ZhbHVlID4gMCwgbW90cl92YWx1ZSA+IDApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxZS01KSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+PSAwLjMpCiAgIyBtdXRhdGUoZXlldHJfdmFsdWUgPSBleHAoZXlldHJfdmFsdWUpLAogICAgICAgICAjIG1vdHJfdmFsdWUgPSBleHAobW90cl92YWx1ZSkKICAgICAgICAgIyApCiMgVmlldyhyZWdfZGYpCgpwcmludChjb3IudGVzdChyZWdfZGZfaGlnaCRleWV0cl92YWx1ZSwgcmVnX2RmX2hpZ2gkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaCRtb3RyX3ZhbHVlKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChyZWdfZGZfaGlnaF9kcm9wMCRleWV0cl92YWx1ZSwgcmVnX2RmX2hpZ2hfZHJvcDAkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoX2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaF9kcm9wMCRtb3RyX3ZhbHVlKSRwLnZhbHVlKQoKIyBWaWV3KHJlZ19kZikKcmVnX2RmX2hpZ2ggJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTMpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXBfaGlnaCA8LSByZWdfZGZfaGlnaFtjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCnJlZ190ZW1wX2hpZ2hfZHJvcDAgPC0gcmVnX2RmX2hpZ2hfZHJvcDBbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMykpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggdGRfdGVtcApwbG90KHJlZ190ZW1wX2FsbCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIG5vdCBsb2dnZWQgYWxsIGRhdGEiKQpwbG90KHJlZ190ZW1wX2xvdywgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIG5vdCBsb2dnZWQgZXlldHIgPCAwLjMgIikKcGxvdChyZWdfdGVtcF9oaWdoLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgbm90IGxvZ2dlZCBleWV0ciA+PSAwLjMiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgRlBSZWcgPj0gMC4zIC0tLS0tLS0tLS0KcmVnX2RhdGEgPSBsaXN0KHg9cmVnX3RlbXBfaGlnaF9kcm9wMCwgTj1ucm93KHJlZ190ZW1wX2hpZ2hfZHJvcDApKQpmaXRfcmVnID0gc3RhbigKICAjIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9iZXRhX2NvcnJlbGF0aW9uX3JlZy5zdGFuIiwgCiAgZmlsZSA9ICJzdGFuX21vZGVscy9iaXZhcmlhdGVfbm9ybWFsX3JlZy5zdGFuIiwKICBkYXRhPXJlZ19kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz00LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfcmVnQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9yZWcsIGZpbGUgPSBwYXN0ZTAoIi4vL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMV9kcm9wMHMucmRzIikpCmBgYAoKCgpgYGB7cn0KZml0X21yZWdfYWxsID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfYWxsX2RhdGEucmRzIikKZml0X21yZWdfYWxsX2Ryb3AwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfYWxsX2RhdGFfZHJvcDBzLnJkcyIpCmZpdF9tcmVnX2xvdyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbl8yMDIzL21vdHJfZXlldHJfRlBSZWdfY29yXzAwLTAzLnJkcyIpCmZpdF9tcmVnX2xvd19kcm9wMCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbl8yMDIzL21vdHJfZXlldHJfRlBSZWdfY29yXzAwLTAzX2Ryb3Awcy5yZHMiKQpmaXRfbXJlZ19oaWdoID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMS5yZHMiKQpmaXRfbXJlZ19oaWdoX2Ryb3AwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDMtMV9kcm9wMHMucmRzIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLiBhbGwgZGF0YSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2FsbCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19hbGxfZHJvcDApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLjwgMC4zLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19sb3cpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLjwgMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19sb3dfZHJvcDApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLj49IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21yZWdfaGlnaCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuPj0gMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19oaWdoX2Ryb3AwKQpgYGAKCmBgYHtyfQojICMgRlBSZWcgYWxsIGRhdGEKIyBzdGFuX3RyYWNlKGZpdF9tcmVnX2FsbCkKIyBzdGFuX2RlbnMoZml0X21yZWdfYWxsLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfbXJlZ19hbGwpCgojIHN0YW5fdHJhY2UoZml0X21yZWdfYWxsX2Ryb3AwKQojIHN0YW5fZGVucyhmaXRfbXJlZ19hbGxfZHJvcDAsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2FsbF9kcm9wMCkKCiMgIyBGUFJlZyA8IDAuMwojIHN0YW5fdHJhY2UoZml0X21yZWdfbG93KQojIHN0YW5fZGVucyhmaXRfbXJlZ19sb3csIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2xvdykKIyAKIyBzdGFuX3RyYWNlKGZpdF9tcmVnX2xvd19kcm9wMCkKIyBzdGFuX2RlbnMoZml0X21yZWdfbG93X2Ryb3AwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfbXJlZ19sb3dfZHJvcDApCgojIEZQUmVnID4gMC4zCnN0YW5fdHJhY2UoZml0X21yZWdfaGlnaCkKc3Rhbl9kZW5zKGZpdF9tcmVnX2hpZ2gsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfbXJlZ19oaWdoKQoKc3Rhbl90cmFjZShmaXRfbXJlZ19oaWdoX2Ryb3AwKQpzdGFuX2RlbnMoZml0X21yZWdfaGlnaF9kcm9wMCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9tcmVnX2hpZ2hfZHJvcDApCmBgYAoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfYWxsID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2FsbCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2FsbCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfYWxsLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfYWxsKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19hbGxfZHJvcDAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21yZWdfYWxsX2Ryb3AwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfYWxsX2Ryb3AwKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19hbGxfZHJvcDAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbXJlZ19hbGxfZHJvcDApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPCAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tcmVnX2xvdyA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfbXJlZ19sb3csICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19sb3cpCmNySSA9IHF1YW50aWxlKHJob19tcmVnX2xvdywgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19tcmVnX2xvdyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyBubyAwcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfbG93X2Ryb3AwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2xvd19kcm9wMCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2xvd19kcm9wMCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfbG93X2Ryb3AwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfbG93X2Ryb3AwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfaGlnaCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfbXJlZ19oaWdoLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfaGlnaCkKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfaGlnaCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19tcmVnX2hpZ2gpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPj0gMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19oaWdoX2Ryb3AwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2hpZ2hfZHJvcDAsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19oaWdoX2Ryb3AwKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19oaWdoX2Ryb3AwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfaGlnaF9kcm9wMCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWFsbHJlZ19yYW5kIDwtIGV4dHJhY3QoZml0X21yZWdfYWxsLCAieF9yYW5kIilbWzFdXQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1hbGxyZWdfcmFuZFssMV0sIG1hbGxyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2FsbCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWFsbHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YSBubyAwcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWFsbHJlZ19yYW5kX2Ryb3AwIDwtIGV4dHJhY3QoZml0X21yZWdfYWxsX2Ryb3AwLCAieF9yYW5kIilbWzFdXQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1hbGxyZWdfcmFuZF9kcm9wMFssMV0sIG1hbGxyZWdfcmFuZF9kcm9wMFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2FsbCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtYWxscmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWFsbHJlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1sb3dyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2xvdywgInhfcmFuZCIpW1sxXV0KcHJpbnQobWxvd3JlZ19yYW5kKQojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1sb3dyZWdfcmFuZFssMV0sIG1sb3dyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2xvdywgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWxvd3JlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMyBubyAwcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1sb3dyZWdfcmFuZF9kcm9wMCA8LSBleHRyYWN0KGZpdF9tcmVnX2xvd19kcm9wMCwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWxvd3JlZ19yYW5kX2Ryb3AwWywxXSwgbWxvd3JlZ19yYW5kX2Ryb3AwWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXBfbG93X2Ryb3AwLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1sb3dyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtbG93cmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1oaWdocmVnX3JhbmRfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgcHJpbnQobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3cobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKSwgOTAwKQptaGlnaHJlZ19yYW5kIDwtIG1oaWdocmVnX3JhbmRfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCiMgbWhpZ2hyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWhpZ2hyZWdfcmFuZFssMV0sIG1oaWdocmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcF9oaWdoLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1oaWdocmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWhpZ2hyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgojIHByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMgbm8gMHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptaGlnaHJlZ19yYW5kX2Ryb3AwX3NhbXBsZXMgPC0gZXh0cmFjdChmaXRfbXJlZ19oaWdoX2Ryb3AwLCAieF9yYW5kIilbWzFdXQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3cobWhpZ2hyZWdfcmFuZF9kcm9wMF9zYW1wbGVzKSwgOTAwKQptaGlnaHJlZ19yYW5kX2Ryb3AwIDwtIG1oaWdocmVnX3JhbmRfZHJvcDBfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvcgpwb2ludHMobWhpZ2hyZWdfcmFuZF9kcm9wMFssMV0sIG1oaWdocmVnX3JhbmRfZHJvcDBbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcF9oaWdoX2Ryb3AwLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IKZGF0YUVsbGlwc2UobWhpZ2hyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtaGlnaHJlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCmBgYAoKCiMgbW9kZWwgZXllIHRyYWNraW5nIHRvIGV5ZSB0cmFja2luZyBjb3JyZWxhdGlvbgpgYGB7cn0KCnByaW50KCJHYXplIER1cmF0aW9uIikKIyBWaWV3KHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYpCgplZ2RfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgICBmaWx0ZXIodGV4dF9pZCAhPSAxOCkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMSksCiAgICAgICAgIGV5ZXRyX3ZhbHVlXzIgPSBwbWF4KHZhbHVlXzIsIDEpCiAgKSAKcHJpbnQoY29yLnRlc3QoZWdkX2RmJGV5ZXRyX3ZhbHVlXzEsIGVnZF9kZiRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKCiMgVmlldyhlZ2RfZGYpCgplZ2RfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgNTo2KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmVnZF90ZW1wIDwtIGVnZF9kZltjKCJleWV0cl92YWx1ZV8xIiwgImV5ZXRyX3ZhbHVlXzIiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KGVnZF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCgpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQplZ2RfZGF0YSA9IGxpc3QoeD1lZ2RfdGVtcCwgTj1ucm93KGVnZF90ZW1wKSkKCmZpdF9lZ2QgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1lZ2RfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VnZEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZWdkLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vY29yX2JpdmFyaWF0ZS9leWV0cl9leWV0cl9nYXplX2R1cmF0aW9uX2Nvci5yZHMiKSkKCmBgYAoKYGBge3J9CnByaW50KCJHbyBQYXN0IFRpbWUiKQoKZWdwdF9kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdvX3Bhc3RfdGltZSIpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGZpbHRlcih0ZXh0X2lkICE9IDE4KSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxKSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMSkKICApIApwcmludChjb3IudGVzdChlZ3B0X2RmJGV5ZXRyX3ZhbHVlXzEsIGVncHRfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCgojIFZpZXcoZWdkX2RmKQoKZWdwdF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZWdwdF90ZW1wIDwtIGVncHRfZGZbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChlZ3B0X3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KZWdwdF9kYXRhID0gbGlzdCh4PWVncHRfdGVtcCwgTj1ucm93KGVncHRfdGVtcCkpCgpmaXRfZWdwdCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVncHRfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VncHRAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2VncHQsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9nb19wYXN0X3RpbWVfY29yLnJkcyIpKQoKYGBgCgoKYGBge3J9CnByaW50KCJUb3RhbCBEdXJhdGlvbiIpCgpldGRfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJ0b3RhbF9kdXJhdGlvbiIpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUsIG5hLnJtID0gVFJVRSksIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGZpbHRlcih0ZXh0X2lkICE9IDE4KSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxKSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMSkKICApIApwcmludChjb3IudGVzdChldGRfZGYkZXlldHJfdmFsdWVfMSwgZXRkX2RmJGV5ZXRyX3ZhbHVlXzIpJGVzdGltYXRlKQoKIyBWaWV3KGVnZF9kZikKCmV0ZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXRkX3RlbXAgPC0gZXRkX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXRkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJUb3RhbCBEdXJhdGlvbiBOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CmV0ZF9kYXRhID0gbGlzdCh4PWV0ZF90ZW1wLCBOPW5yb3coZXRkX3RlbXApKQoKZml0X2V0ZCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWV0ZF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICAjIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9ldGRAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2V0ZCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvci5yZHMiKSkKYGBgCgoKYGBge3J9CnByaW50KCJGaXNydCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4iKQoKZXJlZ19kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIGRpc3RpbmN0KCkgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSkpICU+JQogICMgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAKICAjID09PT0gZm9yIG5vcm1hbCBkYXRhIGRyb3AwcyA9PT09CiAgIyBmaWx0ZXIodmFsdWVfMSA+IDAsIHZhbHVlXzIgPiAwKSAlPiUKICAjIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMWUtNSksCiAgIyAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkKICAjICkKICAKICAjID09PT0gZm9yIHJhbmtpbmcgdGhlIGRhdGEgZHJvcDBzID09PT0KICAgIG11dGF0ZSgKICAgIGV5ZXRyX3ZhbHVlXzEgPSBpZmVsc2UodmFsdWVfMSA+IDAsIHJhbmsodmFsdWVfMSksIE5BKSwKICAgIGV5ZXRyX3ZhbHVlXzIgPSBpZmVsc2UodmFsdWVfMiA+IDAsIHJhbmsodmFsdWVfMiksIE5BKQogICkgJT4lCiAgZHJvcF9uYSgpCgogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSB3LyAwcyA9PT09CiAgIyAgIG11dGF0ZSgKICAjICAgZXlldHJfdmFsdWVfMSA9IHJhbmsodmFsdWVfMSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAogICMgICBleWV0cl92YWx1ZV8yID0gcmFuayh2YWx1ZV8yLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKICAjICkKCgpwcmludChjb3IudGVzdChlcmVnX2RmJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCgojIFZpZXcoZWdkX2RmKQoKZXJlZ19kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXJlZ190ZW1wIDwtIGVyZWdfZGZbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRyb3BfbmEoKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyAtLS0tLS0tLS0tCgojIFZpZXcoZXJlZ190ZW1wKQplcmVnX2RhdGEgPSBsaXN0KHg9ZXJlZ190ZW1wLCBOPW5yb3coZXJlZ190ZW1wKSkKZml0X2VyZWcgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbl9yYW5rLnN0YW4iLCAKICBkYXRhPWVyZWdfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZXJlZ0BzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXJlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9yYW5rX2Ryb3Awcy5yZHMiKSkKYGBgCgpgYGB7cn0KcHJpbnQoIlNraXAgUHJvYi4iKQoKZXNraXBfZGYgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJza2lwIikgJT4lIGRpc3RpbmN0KCkgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSkpICU+JQogICMgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKQogIAogICMgPT09PSBmb3Igbm9ybWFsIGRhdGEgZHJvcDBzID09PT0KICAjIGZpbHRlcih2YWx1ZV8xID4gMCwgdmFsdWVfMiA+IDApICU+JQogICMgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAjICAgICAgICBleWV0cl92YWx1ZV8yID0gcG1heCh2YWx1ZV8yLCAxZS01KQogICMgKQogIAogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSBkcm9wMHMgPT09PQogICMgICBtdXRhdGUoCiAgIyAgIGV5ZXRyX3ZhbHVlXzEgPSBpZmVsc2UodmFsdWVfMSA+IDAsIHJhbmsodmFsdWVfMSksIE5BKSwKICAjICAgZXlldHJfdmFsdWVfMiA9IGlmZWxzZSh2YWx1ZV8yID4gMCwgcmFuayh2YWx1ZV8yKSwgTkEpCiAgIyApICU+JQogICMgZHJvcF9uYSgpCgogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSB3LyAwcyA9PT09CiAgIyAgIG11dGF0ZSgKICAjICAgZXlldHJfdmFsdWVfMSA9IHJhbmsodmFsdWVfMSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpLAogICMgICBleWV0cl92YWx1ZV8yID0gcmFuayh2YWx1ZV8yLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIikKICAjICkKCgpwcmludChjb3IudGVzdChlc2tpcF9kZiR2YWx1ZV8xLCBlc2tpcF9kZiR2YWx1ZV8yKSRlc3RpbWF0ZSkKCgplc2tpcF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZXNraXBfdGVtcCA8LSBlc2tpcF9kZltjKCJ2YWx1ZV8xIiwgInZhbHVlXzIiKV0gJT4lCiAgZHJvcF9uYSgpICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChlc2tpcF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiU2tpcCBOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIFNraXAgLS0tLS0tLS0tLQoKIyBWaWV3KGVyZWdfdGVtcCkKZXNraXBfZGF0YSA9IGxpc3QoeD1lc2tpcF90ZW1wLCBOPW5yb3coZXNraXBfdGVtcCkpCmZpdF9lc2tpcCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX25vcm1hbF9yZWcuc3RhbiIsIAogIGRhdGE9ZXNraXBfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZXNraXBAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2Vza2lwLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfc2tpcF9jb3JfZHJvcDBzLnJkcyIpKQpgYGAKCgoKYGBge3J9CmZpdF9lZ2QgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfZ2F6ZV9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpCmZpdF9lZ3B0ID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpCmZpdF9ldGQgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQpmaXRfZXJlZyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfZHJvcDBzLnJkcyIpCmZpdF9lc2tpcCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9za2lwX2Nvcl9kcm9wMHMucmRzIikKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VnZCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR28gUGFzdCBUaW1lLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfZWdwdCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9ldGQpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWcpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFNraXAgUHJvYi4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9lc2tpcCkKYGBgCgoKYGBge3IsIGV2YWw9RkFMU0V9CiMgc3Rhbl90cmFjZShmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQojIHN0YW5fZGVucyhmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQojIHN0YW5fcGxvdChmaXRfZWdkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQoKIyBHYXplIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2VnZCkKc3Rhbl9kZW5zKGZpdF9lZ2QsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZWdkKQoKIyBHbyBQYXN0IFRpbWUKc3Rhbl90cmFjZShmaXRfZWdwdCkKc3Rhbl9kZW5zKGZpdF9lZ3B0LCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VncHQpCgojIFRvdGFsIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2V0ZCkKc3Rhbl9kZW5zKGZpdF9ldGQsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZXRkKQoKIyBGUFJlZwpzdGFuX3RyYWNlKGZpdF9lcmVnKQpzdGFuX2RlbnMoZml0X2VyZWcsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZXJlZykKYGBgCgoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lZ2QgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VnZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZ2QpCmNySSA9IHF1YW50aWxlKHJob19lZ2QsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZWdkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR28gUGFzdCBUaW1lLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZWdwdCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZWdwdCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZ3B0KQpjckkgPSBxdWFudGlsZShyaG9fZWdwdCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19lZ3B0KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19ldGQgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2V0ZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19ldGQpCmNySSA9IHF1YW50aWxlKHJob19ldGQsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXRkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VyZWcsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZXJlZykKY3JJID0gcXVhbnRpbGUocmhvX2VyZWcsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXJlZyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFNraXAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXNraXAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2Vza2lwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2Vza2lwKQpjckkgPSBxdWFudGlsZShyaG9fZXNraXAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXNraXApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQpgYGAKCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWdkX3JhbmQgPC0gZXh0cmFjdChmaXRfZWdkLCAieF9yYW5kIilbWzFdXQojIHhfcmFuZF9maWx0ZXJlZCA8LSB4X3JhbmRbYXBwbHkoeF9yYW5kLCAxLCBmdW5jdGlvbih4KSBhbGwoeCA+IDApKSxdCiMgeF9yYW5kX2ZpbHRlcmVkCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgNDAwKSwgeWxpbT1jKDAsIDcwMCksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDEiLCB5bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAyIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVnZF9yYW5kWywxXSwgZWdkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ2RfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVncHRfcmFuZCA8LSBleHRyYWN0KGZpdF9lZ3B0LCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIkdvIFBhc3QgVGltZSIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZ3B0X3JhbmRbLDFdLCBlZ3B0X3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ3B0X3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVncHRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZXRkX3JhbmQgPC0gZXh0cmFjdChmaXRfZXRkLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIlRvdGFsIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGV0ZF9yYW5kWywxXSwgZXRkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhldGRfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplcmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZywgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAxIiwgeWxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMiIsIG1haW4gPSAiRmlyc3QgUGFzcyBSZWdyZXNzaW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVyZWdfcmFuZFssMV0sIGVyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVyZWdfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlcmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZXJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKYGBgCgoKIyBCYXllc2lhbiAtLSBjb3JyZWxhdGlvbiBiZXR3ZWVuIE1vVFIgYW5kIHdvcmQgbGV2ZWwgc3RhdGlzdGljcwpgYGB7cn0KcHJpbnQoIkxvZyBGcmVxdWVuY3kiKQpzdGF0c19jb3JfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiZ2F6ZV9kdXJhdGlvbiIpICU+JSBzcHJlYWQobWVhc3VyZSwgdmFsdWUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRtb3RyX3ZhbHVlLCBzdGF0c19jb3JfZGYkZnJlcSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGZyZXEpJGVzdGltYXRlKQoKIyBWaWV3KHN0YXRzX2Nvcl9kZikKc3RhdHNfY29yX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIGMoNywgMTMpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCm1mcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoIm1vdHJfdmFsdWUiLCAiZnJlcSIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVmcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoImV5ZXRyX3ZhbHVlIiwgImZyZXEiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KG1mcmVxX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWZyZXFfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKYGBgCiMgbW90ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KbWZyZXFfZGF0YSA9IGxpc3QoeD1tZnJlcV90ZW1wLCBOPW5yb3cobWZyZXFfdGVtcCkpCgpmaXRfbWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1mcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21mcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZnJlcV9jb3IucmRzIikpCmBgYAoKIyBleWV0ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KZWZyZXFfZGF0YSA9IGxpc3QoeD1lZnJlcV90ZW1wLCBOPW5yb3coZWZyZXFfdGVtcCkpCgpmaXRfZWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVmcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VmcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9lZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2ZyZXFfY29yLnJkcyIpKQpgYGAKCmBgYHtyfQpwcmludCgiTGVuZ3RoIikKc3RhdHNfY29yX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdhemVfZHVyYXRpb24iKSAlPiUgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKQpwcmludChjb3IudGVzdChzdGF0c19jb3JfZGYkbW90cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg5LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbWxlbl90ZW1wIDwtIHN0YXRzX2Nvcl9kZltjKCJtb3RyX3ZhbHVlIiwgImxlbiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVsZW5fdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAibGVuIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChtbGVuX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBMZW5ndGgiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWxlbl90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRXllVFIgUlRzIGFuZCBXb3JkIExlbmd0aCIpCmBgYAoKIyBtb3RyICYgbGVuZ3RoCmBgYHtyLCBldmFsPUZBTFNFfQptbGVuX2RhdGEgPSBsaXN0KHg9bWxlbl90ZW1wLCBOPW5yb3cobWxlbl90ZW1wKSkKCmZpdF9tbGVuID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbl9sZW5fbm9ybWFsLnN0YW4iLCAKICBkYXRhPW1sZW5fZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgIyB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfbWxlbkBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfbWxlbiwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfbGVuX2Nvci5yZHMiKSkKCmBgYAoKIyBleWV0ciAmIGxlbmd0aApgYGB7ciwgZXZhbD1GQUxTRX0KZWxlbl9kYXRhID0gbGlzdCh4PWVsZW5fdGVtcCwgTj1ucm93KGVsZW5fdGVtcCkpCgpmaXRfZWxlbiA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvc3RhdHNfY29ycmVsYXRpb25fbGVuX25vcm1hbC5zdGFuIiwgCiAgZGF0YT1lbGVuX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VsZW5Ac3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2VsZW4sIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9sZW5fY29yLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIlN1cnByaXNhbCIpCnN0YXRzX2Nvcl9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJG1vdHJfdmFsdWUsIHN0YXRzX2Nvcl9kZiRzdXJwKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJGV5ZXRyX3ZhbHVlLCBzdGF0c19jb3JfZGYkc3VycCkkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg4LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygibW90cl92YWx1ZSIsICJzdXJwIildICU+JQogIGRhdGEubWF0cml4KCkKZXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAic3VycCIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QobXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk1vVFIgUlRzIGFuZCBTdXJwcmlzYWwiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgU3VycHJpc2FsIikKYGBgCiMgbW90ciAmIHN1cnByaXNhbApgYGB7ciwgZXZhbD1GQUxTRX0KbXN1cnBfZGF0YSA9IGxpc3QoeD1tc3VycF90ZW1wLCBOPW5yb3cobXN1cnBfdGVtcCkpCgpmaXRfbXN1cnAgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1zdXJwX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21zdXJwQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tc3VycCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikpCgpgYGAKCiMgZXlldHIgJiBzdXJwcmlzYWwKYGBge3IsIGV2YWw9RkFMU0V9CmVzdXJwX2RhdGEgPSBsaXN0KHg9ZXN1cnBfdGVtcCwgTj1ucm93KGVzdXJwX3RlbXApKQoKZml0X2VzdXJwID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1lc3VycF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICAjIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9lc3VycEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXN1cnAsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9zdXJwX2Nvci5yZHMiKSkKCmBgYAoKCmBgYHtyfQpmaXRfbWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9mcmVxX2Nvci5yZHMiKQpmaXRfZWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZnJlcV9jb3IucmRzIikKZml0X21sZW4gPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9sZW5fY29yLnJkcyIpCmZpdF9lbGVuID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2xlbl9jb3IucmRzIikKZml0X21zdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikKZml0X2VzdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX3N1cnBfY29yLnJkcyIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXF1ZW5jeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tZnJlcSkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBMb2cgRnJlcXVlbmN5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VmcmVxKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21sZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VsZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXN1cnApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VzdXJwKQoKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyBNb1RSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfbWZyZXEpCnN0YW5fZGVucyhmaXRfbWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfbWZyZXEpCgojIEV5ZVRSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfZWZyZXEpCnN0YW5fZGVucyhmaXRfZWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZWZyZXEpCgojIE1vVFIgJiBMZW4Kc3Rhbl90cmFjZShmaXRfbWxlbikKc3Rhbl9kZW5zKGZpdF9tbGVuLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21sZW4pCgojIEV5ZVRSICYgTGVuCnN0YW5fdHJhY2UoZml0X2VsZW4pCnN0YW5fZGVucyhmaXRfZWxlbiwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lbGVuKQoKIyBNb1RSICYgU3VycHJpc2FsCnN0YW5fdHJhY2UoZml0X21zdXJwKQpzdGFuX2RlbnMoZml0X21zdXJwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21zdXJwKQoKIyBFeWVUUiAmIFN1cnByaXNhbApzdGFuX3RyYWNlKGZpdF9lc3VycCkKc3Rhbl9kZW5zKGZpdF9lc3VycCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lc3VycCkKCmBgYAoKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbWZyZXEgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21mcmVxLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21mcmVxKQpjckkgPSBxdWFudGlsZShyaG9fbWZyZXEsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbWZyZXEpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExvZyBGcmVxIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VmcmVxID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lZnJlcSwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZnJlcSkKY3JJID0gcXVhbnRpbGUocmhvX2VmcmVxLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VmcmVxKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21sZW4pCmNySSA9IHF1YW50aWxlKHJob19tbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21sZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VsZW4pCmNySSA9IHF1YW50aWxlKHJob19lbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VsZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21zdXJwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tc3VycCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tc3VycCkKY3JJID0gcXVhbnRpbGUocmhvX21zdXJwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21zdXJwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXN1cnAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VzdXJwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VzdXJwKQpjckkgPSBxdWFudGlsZShyaG9fZXN1cnAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXN1cnApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQoKYGBgCgoKCmBgYHtyLGV2YWw9RkFMU0V9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMb2cgRnJlcXVlbmN5LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptZnJlcV9yYW5kIDwtIGV4dHJhY3QoZml0X21mcmVxLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMiksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiTW9UUiB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtZnJlcV9yYW5kWywxXSwgbWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1mcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UobWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTG9nIEZyZXF1ZW5jeS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWZyZXFfcmFuZCA8LSBleHRyYWN0KGZpdF9lZnJlcSwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA1MDApLCB5bGltPWMoMCwgMTIpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZnJlcV9yYW5kWywxXSwgZWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVmcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMZW5ndGggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptbGVuX3JhbmQgPC0gZXh0cmFjdChmaXRfbWxlbiwgInhfcmFuZCIpW1sxXV0KIyBtbGVuX3JhbmQKCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA4MDApLCB5bGltPWMoMCwgMjApLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIk1vVFIgdmFsdWUiLCB5bGFiID0gIldvcmQgTGVuZ3RoIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1sZW5fcmFuZFssMV0sIG1sZW5fcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1sZW5fdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtbGVuX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWxlbl9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxlbl9yYW5kIDwtIGV4dHJhY3QoZml0X2VsZW4sICJ4X3JhbmQiKVtbMV1dCiMgZWxlbl9yYW5kCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBMZW5ndGgiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWxlbl9yYW5kWywxXSwgZWxlbl9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZWxlbl90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsZW5fcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbGVuX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1zdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfbXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJNb1RSIHZhbHVlIiwgeWxhYiA9ICJXb3JkIFN1cnByaXNhbCIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtc3VycF9yYW5kIFssMV0sIG1zdXJwX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhtc3VycF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1zdXJwX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobXN1cnBfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVzdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfZXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBTdXJwcmlzYWwiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZXN1cnBfcmFuZCBbLDFdLCBlc3VycF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXN1cnBfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlc3VycF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVzdXJwX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCgoKYGBge3J9CnByaW50KCJFeWVUUiB2cy4gRXllVFIgRmlzcnQgUGFzcyBSZWdyZXNzaW9uIFByb2IuIDwgMC4zICIpCgplcmVnX2RmID0gcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgZGlzdGluY3QoKSAlPiUgI2dyb3VwX2J5KHRleHRfaWQsIG1ldHJpYywgbWVhc3VyZSkgJT4lCiAgIyBzdW1tYXJpemUodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMWUtNSksCiAgICAgICAgIGV5ZXRyX3ZhbHVlXzIgPSBwbWF4KHZhbHVlXzIsIDFlLTUpKQoKZXJlZ19kZl9sb3cgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xIDwgMC4zKQojIFZpZXcoZXJlZ19kZl9sb3cpCgplcmVnX2RmX2hpZ2ggPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xID49IDAuMykKIyBWaWV3KGVyZWdfZGZfaGlnaCkgCgpwcmludChjb3IudGVzdChlcmVnX2RmJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGVyZWdfZGYkZXlldHJfdmFsdWVfMSwgZXJlZ19kZiRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8xLCBlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMSwgZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMikkcC52YWx1ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQoKIyBWaWV3KGVnZF9kZikKCmVyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgNTo2KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmVyZWdfdGVtcCA8LSBlcmVnX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfbG93IDwtIGVyZWdfZGZfbG93W2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfaGlnaCA8LSBlcmVnX2RmX2hpZ2hbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRyb3BfbmEoKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAzKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgYWxsIGRhdGEgTm90IExvZy1UcmFuc2Zvcm1lZCIpCnBsb3QoZXJlZ190ZW1wX2xvdywgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIDwgMC4zIE5vdCBMb2ctVHJhbnNmb3JtZWQiKQpwbG90KGVyZWdfdGVtcF9oaWdoLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgPiAwLjMgTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgZXlldHIgdnMuIGV5ZXRyIEZQUmVnIDwwLjMgJiA+PTAuMyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PWVyZWdfdGVtcCwgTj1ucm93KGVyZWdfdGVtcCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKSkKYGBgCgoKCiMgZXhwbG9yYXRvcnk6IGRpdmlkZSBleWUgdHJhY2tpbmcgcmVncmVzc2lvbiBkYXRhIGludG8gdHdvIHBhcnRzLgpgYGB7cn0KIyBmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKQpmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfRlBSZWdfY29yLnJkcyIpCmZpdF9lcmVnX2xvdyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDAtMDMucmRzIikKZml0X2VyZWdfaGlnaCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDMtMS5yZHMiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfYWxsKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi48IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfbG93KQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9lcmVnX2hpZ2gpCgpgYGAKCgpgYGB7cn0KIyAjIEZQUmVnIGFsbCBkYXRhCnN0YW5fdHJhY2UoZml0X2VyZWdfYWxsKQpzdGFuX2RlbnMoZml0X2VyZWdfYWxsLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfYWxsKQoKIyAjIEZQUmVnIDwgMC4zCnN0YW5fdHJhY2UoZml0X2VyZWdfbG93KQpzdGFuX2RlbnMoZml0X2VyZWdfbG93LCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfbG93KQoKIyBGUFJlZyA+PSAwLjMKc3Rhbl90cmFjZShmaXRfZXJlZ19oaWdoKQpzdGFuX2RlbnMoZml0X2VyZWdfaGlnaCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lcmVnX2hpZ2gpCmBgYAoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfYWxsID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2FsbCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2FsbCkKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfYWxsLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfYWxsKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfbG93ID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2xvdywgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2xvdykKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfbG93LCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfbG93KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lcmVnX2hpZ2ggPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VyZWdfaGlnaCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2hpZ2gpCmNySSA9IHF1YW50aWxlKHJob19lcmVnX2hpZ2gsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXJlZ19oaWdoKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQpgYGAKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gYWxsIGRhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplYWxscmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZ19hbGwsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWFsbHJlZ19yYW5kWywxXSwgZWFsbHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXJlZ190ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVhbGxyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxvd3JlZ19yYW5kIDwtIGV4dHJhY3QoZml0X2VyZWdfbG93LCAieF9yYW5kIilbWzFdXQojIHByaW50KGVsb3dyZWdfcmFuZCkKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlbG93cmVnX3JhbmRbLDFdLCBlbG93cmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfbG93LCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsb3dyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVoaWdocmVnX3JhbmRfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9lcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgcHJpbnQobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3coZWhpZ2hyZWdfcmFuZF9zYW1wbGVzKSwgOTAwKQplaGlnaHJlZ19yYW5kIDwtIGVoaWdocmVnX3JhbmRfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCiMgbWhpZ2hyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWhpZ2hyZWdfcmFuZFssMV0sIGVoaWdocmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfaGlnaCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlaGlnaHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVoaWdocmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCg==